При разработке внешних обработок, механизмов интеграции и заполнении документов часто возникает задача: сформировать пустую ТаблицаЗначений, состав колонок и типы данных которой в точности повторяют табличную часть конкретного документа конфигурации (например, табличную часть Товары документа РеализацияТоваровУслуг).
Создавать полноценный экземпляр документа через Документы.РеализацияТоваровУслуг.СоздатьДокумент() ради получения пустой структуры неэффективно, так как это вызывает инициализацию объекта, срабатывание обработчиков событий и избыточно расходует оперативную память сервера. Разберем и сравним все доступные способы решения этой задачи в платформе 1С:Предприятие.
Рассмотрим наиболее компактный и элегантный синтаксический способ. Платформа 1С позволяет обратиться к табличной части через пустую ссылку на документ и вызвать специализированный метод ВыгрузитьКолонки().
Посмотрим на пример программного кода:
// Получаем пустую таблицу значений с колонками табличной части
ТЗ = Документы.РеализацияТоваровУслуг.ПустаяСсылка().Товары.ВыгрузитьКолонки();
Разберем подробнее, как этот метод устроен изнутри и что происходит на уровне платформы:
ПустаяСсылка() возвращает ссылку с пустым уникальным идентификатором.Товары платформа не создает объект типа ДокументОбъект (события ОбработкаЗаполнения или ПередЗаписью не выполняются).ВыгрузитьКолонки() возвращает объект ТаблицаЗначений, содержащий все колонки табличной части с точным сохранением их типов данных (ОписаниеТипов).Важный нюанс: при обращении к табличной части через пустую ссылку платформа отправляет быстрый SQL-запрос к таблице СУБД с условием по нулевому GUID, чтобы инициализировать пустую коллекцию. Это работает быстро, но требует наличия прав на чтение таблицы документа.
Проанализируем второй популярный метод — использование языка запросов 1С с конструкцией ВЫБРАТЬ ПЕРВЫЕ 0. Этот подход позволяет получить результат запроса с предопределенной структурой полей без считывания реальных записей из базы данных.
Посмотрим на пример реализации:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 0
| *
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТовары";
ТЗ = Запрос.Выполнить().Выгрузить();
// При необходимости удаляем системное поле Ссылка
Если ТЗ.Колонки.Найти("Ссылка") <> Неопределено Тогда
ТЗ.Колонки.Удалить("Ссылка");
КонецЕсли;
Разберем плюсы и подводные камни запросного метода:
*) в результирующую таблицу значений автоматически попадают служебные поля СУБД — Ссылка и НомерСтроки. Если полученную таблицу планируется передавать в метод ТабличнаяЧасть.Загрузить(ТЗ), лишнюю колонку Ссылка следует предварительно удалить, чтобы избежать ошибок несоответствия типов.Выясним причину, почему обход дерева метаданных считается наиболее производительным и надежным подходом для высоконагруженных сценариев. Это единственный метод, который работает исключительно с кэшем конфигурации в оперативной памяти и не выполняет сетевых обращений к СУБД.
Посмотрим на реализацию универсального алгоритма:
ТЗ = Новый ТаблицаЗначений;
// Получаем объект метаданных табличной части
МетаданныеТЧ = Метаданные.Документы.РеализацияТоваровУслуг.ТабличныеЧасти.Товары;
// Добавляем реквизиты табличной части
Для Каждого Реквизит Из МетаданныеТЧ.Реквизиты Цикл
ТЗ.Колонки.Добавить(Реквизит.Имя, Реквизит.Тип, Реквизит.Синоним);
КонецЦикла;
Преимущества создания таблицы через Метаданные:
Ссылка.Если разработка ведется в типовой конфигурации на базе Библиотеки Стандартных Подсистем (БСП), нет необходимости дублировать логику обхода метаданных. В общем модуле ОбщегоНазначения предусмотрены готовые сервисные функции.
Рассмотрим пример использования типового функционала:
// Создание пустой таблицы по описанию метаданных документа
ИмяТЧ = "Документ.РеализацияТоваровУслуг.Товары";
ТЗ = ОбщегоНазначения.ТаблицаЗначенийИзМетаданных(ИмяТЧ);
Также для быстрого копирования структуры между существующими таблицами можно применять метод ОбщегоНазначения.СкопироватьКолонки(), передавая пустую таблицу-источник и таблицу-приемник.
Проанализируем, в какой ситуации лучше выбрать конкретный способ:
ПустаяСсылка().Товары.ВыгрузитьКолонки() — лучший вариант для быстрой разработки и небольших скриптов, когда важен минимальный объем исходного кода.Запрос с ВЫБРАТЬ ПЕРВЫЕ 0 — удобен, если одновременно со структурой колонок нужно наложить условия переименования полей через конструкции КАК или объединить несколько табличных частей.Обход через Метаданные — оптимален для высокопроизводительного серверного кода, циклической обработки больших массивов данных и при строгих настройках прав доступа (RLS).Важное ограничение: объект ТаблицаЗначений не поддерживается на стороне тонкого и веб-клиента. Все описанные операции должны выполняться на сервере (в контексте процедур с директивами &НаСервере или &НаСервереБезКонтекста).