Как в 1С создать колонку таблицы значений со всеми типами документов?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В практике разработчика 1С часто возникают задачи, когда необходимо подготовить универсальное хранилище данных — Таблицу Значений (ТЗ), где одна из колонок должна принимать значения любого документа, существующего в системе. Типичный пример — работа с субконто на счетах бухгалтерского учета, где заранее неизвестно, какой именно вид документа будет выступать в роли аналитики. В этой статье мы подробно разберем, как реализовать это правильно, какие методы предоставляет платформа и с какими подводными камнями можно столкнуться при использовании универсальных типов данных.

Способ 1: Прямое использование метода ТипВсеСсылки()

Начнем с самого простого и лаконичного способа, который часто называют «православным» или стандартным для платформы 1С:Предприятие 8. Рассмотрим ситуацию, когда нам нужно добавить колонку с именем Документ в уже существующую таблицу значений. Для этого мы воспользуемся встроенным менеджером метаданных Документы.

Проанализируем следующий код:


// Создаем новую таблицу значений
ТвояТЗ = Новый ТаблицаЗначений;

// Добавляем колонку с типом «Все ссылки документов»
ТвояТЗ.Колонки.Добавить("Документ", Документы.ТипВсеСсылки());

Разберем, что происходит в этот момент. Метод Документы.ТипВсеСсылки() возвращает готовый объект типа ОписаниеТипов, который уже содержит в себе массив всех типов ссылок на документы, определенных в конфигурации. Это избавляет нас от необходимости вручную перечислять каждый документ в цикле. Данный способ является наиболее быстрым в написании и легко читаемым.

Способ 2: Явное создание объекта ОписаниеТипов

Иногда разработчики по привычке или из соображений дополнительной типизации используют чуть более длинную конструкцию. Рассмотрим ее, чтобы понимать разницу:


// Добавление колонки через конструктор описания типов
ТвояТЗ.Колонки.Добавить("Документ", Новый ОписаниеТипов(Документы.ТипВсеСсылки().Типы()));

Здесь мы сначала получаем список типов из объекта ОписаниеТипов (с помощью метода Типы()), а затем на его основе создаем новый объект ОписаниеТипов. С технической точки зрения это действие избыточно, так как Документы.ТипВсеСсылки() уже возвращает нужный объект. Однако такой подход может быть полезен, если вы планируете комбинировать типы документов с другими типами (например, справочниками) или задавать дополнительные параметры, такие как КвалификаторыСтроки или КвалификаторыЧисла.

Почему важно правильно типизировать колонки ТЗ?

Выясним причину, по которой простого добавления колонки без указания типа (как предлагалось в некоторых сообщениях форума) может быть недостаточно. Рассмотрим пример:


// Добавление колонки без типа
ТЗ.Колонки.Добавить("Документ");

Если вы планируете использовать эту таблицу только для временного хранения данных в памяти в рамках одной процедуры, такой подход сработает. Но если эта ТаблицаЗначений будет передана в качестве параметра в Запрос или использована в Построителе отчетов, система столкнется с проблемой. Запрос не сможет определить метаданные колонки и сопоставить их с таблицами базы данных SQL. Это приведет к ошибке выполнения или к невозможности обращения к полям документа через точку (например, Документ.Дата или Документ.Номер).

Проблемы производительности при использовании «Всех документов»

Проанализируем ситуацию с точки зрения производительности системы, особенно в крупных конфигурациях, таких как 1С:ERP или 1С:УХ. Когда колонка имеет составной тип, включающий в себя несколько сотен видов документов, работа с ней становится «тяжелой».

  1. Нагрузка на SQL-запросы: Если вы передаете ТЗ с такой колонкой в запрос и пытаетесь разыменовать поля (обратиться к реквизитам через точку), СУБД будет вынуждена выполнить LEFT JOIN ко всем таблицам документов, входящих в состав типа. В больших базах это может привести к созданию запроса с сотнями соединений, что вызывает критическое падение скорости или даже падение рабочего процесса сервера 1С.
  2. Индексация: Построить эффективный индекс по колонке с составным типом, содержащим все документы, практически невозможно. Поиск методом НайтиСтроки() по такой колонке будет работать медленнее, чем по четко типизированной.
  3. Передача между клиентом и сервером: Объект ОписаниеТипов для всех документов имеет значительный объем данных при сериализации. При частых вызовах серверных процедур с передачей такой таблицы возрастает нагрузка на сетевой трафик.

Альтернативный подход: Программное ограничение типов

Если мы заранее знаем, что в субконто или в нашей таблице могут быть не абсолютно все документы, а только определенная группа (например, только финансовые или только складские), профессиональной практикой считается программное формирование списка типов. Рассмотрим, как это сделать по шагам:

  1. Создаем пустой Массив.
  2. Перебираем нужные нам метаданные.
  3. Добавляем типы в массив.
  4. Создаем ОписаниеТипов на основе этого массива.

Пример реализации:


МассивТипов = Новый Массив;
// Добавляем только нужные типы вручную или по условию из метаданных
МассивТипов.Добавить(Тип("ДокументСсылка.ПриходныйКассовыйОрдер"));
МассивТипов.Добавить(Тип("ДокументСсылка.РасходныйКассовыйОрдер"));
МассивТипов.Добавить(Тип("ДокументСсылка.РеализацияТоваровУслуг"));

ОписаниеНужныхДокументов = Новый ОписаниеТипов(МассивТипов);
ТвояТЗ.Колонки.Добавить("Документ", ОписаниеНужныхДокументов);

Такой способ значительно «легче» для системы и безопаснее для использования в запросах, так как количество потенциальных соединений в SQL будет ограничено только реально необходимыми таблицами.

Особенности отображения в интерфейсе

Посмотрим на ситуацию со стороны пользователя. Если вы выведете колонку с типом Документы.ТипВсеСсылки() в таблицу на форме, то при нажатии на кнопку выбора («три точки») система откроет огромный список всех документов конфигурации. Это часто путает пользователей.

Чтобы улучшить UX (пользовательский опыт), мы рекомендуем использовать событие НачалоВыбора для элемента формы. В этом событии можно программно ограничить список выбора или открыть специализированную форму подбора, сохранив при этом универсальность хранения данных в самой ТаблицеЗначений.

Резюме

Мы выяснили, что для создания колонки со всеми документами в 1С наиболее эффективным и правильным способом является использование Документы.ТипВсеСсылки(). Это стандарт платформы, который гарантирует корректную работу типизации. Однако всегда стоит помнить о производительности: если количество типов можно ограничить — делайте это. Если таблица будет использоваться в сложных запросах — будьте готовы к оптимизации структуры данных.

← На главную