Разработка и Конфигурация · 10 мин
Как в 1С заполнить табличную часть из таблицы значений
Как в 1С заполнить табличную часть документа или справочника из таблицы значений: метод Загрузить, построчное копирование, типичные ошибки и примеры кода.
Таблица значений в 1С — универсальный промежуточный объект: в неё удобно собирать данные из запроса, файла, обработки или результата расчёта. Рано или поздно эти данные нужно перенести в табличную часть документа, справочника или обработки. Задача выглядит простой, но на практике разработчики сталкиваются с несовпадением колонок, потерей типов и ошибками при работе на управляемых формах.
Существует два основных подхода: метод Загрузить(), который переносит данные целиком за одну операцию, и построчное копирование через цикл с добавлением строк. Первый быстрее и короче, второй даёт контроль над каждой строкой и позволяет преобразовывать данные «на лету». Выбор зависит от того, совпадают ли структуры колонок и нужна ли дополнительная обработка.
Ниже разобраны оба способа с примерами кода, особенности работы на тонком клиенте и управляемых формах, типичные ошибки и способы проверить результат до записи объекта в базу.
Что такое таблица значений и табличная часть
Таблица значений — это несвязанный с базой данных объект в памяти, состоящий из колонок и строк. Её создают программно, получают как результат выгрузки запроса (Запрос.Выполнить().Выгрузить()) или загружают из внешних источников. Данные в ней живут только во время выполнения кода.
Табличная часть — это реквизит объекта конфигурации (документа, справочника, обработки), который хранится в базе вместе с объектом. У табличной части есть фиксированный набор реквизитов с заданными типами, описанный в конфигураторе. Именно поэтому при переносе данных важно совпадение имён и типов колонок.
Способ 1: метод Загрузить()
Метод Загрузить() — стандартный и самый короткий путь. Он очищает табличную часть и заполняет её строками таблицы значений, сопоставляя колонки по именам. Колонки, которых нет в табличной части, игнорируются; реквизиты, которым не нашлось пары, остаются пустыми.
// ТЗ — заранее подготовленная таблица значений
// Например, результат запроса:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Номенклатура, Количество, Цена ИЗ ...";
ТЗ = Запрос.Выполнить().Выгрузить();
// Загрузка в табличную часть документа
ОбъектДокумента.Товары.Загрузить(ТЗ);
Ключевое условие: имена колонок таблицы значений должны совпадать с именами реквизитов табличной части. Если в запросе поле называется НоменклатураСсылка, а реквизит — Номенклатура, используйте псевдоним в запросе (ВЫБРАТЬ Ссылка КАК Номенклатура) или переименуйте колонку перед загрузкой.
Обратите внимание: Загрузить() полностью замещает содержимое табличной части. Если нужно добавить строки к существующим, сначала выгрузите текущие данные методом Выгрузить(), объедините таблицы и только потом загружайте обратно.
Способ 2: построчное заполнение в цикле
Когда структуры не совпадают, нужны вычисления, отбор строк или поиск ссылок по коду и наименованию, применяйте цикл с добавлением строк вручную. Это длиннее, но даёт полный контроль.
Для Каждого СтрокаТЗ Из ТЗ Цикл
Если СтрокаТЗ.Количество = 0 Тогда
Продолжить; // пропускаем нулевые позиции
КонецЕсли;
НоваяСтрока = ОбъектДокумента.Товары.Добавить();
НоваяСтрока.Номенклатура = СтрокаТЗ.Товар;
НоваяСтрока.Количество = СтрокаТЗ.Количество;
НоваяСтрока.Цена = СтрокаТЗ.Цена;
НоваяСтрока.Сумма = СтрокаТЗ.Количество * СтрокаТЗ.Цена;
КонецЦикла;
Этот способ незаменим, когда нужно найти ссылку по значению из файла: например, в таблице значений из Excel хранится артикул, а в табличную часть нужно подставить ссылку на номенклатуру. Поиск выполняется внутри цикла запросом или методом НайтиПоРеквизиту().
- 1Подготовьте таблицу значений и проверьте, что в ней есть нужные колонки
- 2При необходимости очистите табличную часть методом Очистить()
- 3Пройдите циклом по строкам таблицы значений
- 4Для каждой подходящей строки вызовите Добавить() и заполните реквизиты
- 5Выполните пересчёт зависимых полей: суммы, итоги, ставки НДС
- 6Проверьте количество строк и записывайте объект
Работа на управляемых формах
На управляемой форме табличная часть представлена реквизитом формы типа ДанныеФормыКоллекция, а не таблицей значений напрямую. Метод Загрузить() у неё отсутствует — вместо него используется глобальный метод ЗначениеВДанныеФормы() или приём через реквизит объекта.
// Вариант через объект формы
Объект.Товары.Очистить();
Для Каждого СтрокаТЗ Из ТЗ Цикл
НоваяСтрока = Объект.Товары.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТЗ);
КонецЦикла;
Метод ЗаполнитьЗначенияСвойств() копирует значения по совпадающим именам свойств — это удобная замена Загрузить() при построчной обработке на форме. Если таблица значений формируется на сервере, а форма на клиенте, передавайте её через параметры серверной процедуры: таблица значений сериализуется между клиентом и сервером без дополнительных ухищрений.
Сопоставление колонок и типов данных
Большинство проблем при переносе связаны с типами. Если в таблице значений колонка имеет составной тип или тип «Строка», а реквизит табличной части — ссылка на справочник, присвоение либо не выполнится, либо запишет пустое значение. Платформа не выполняет поиск ссылки по строковому представлению автоматически.
Контролируйте типы при создании таблицы значений через ОписаниеТипов:
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Номенклатура",
Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ТЗ.Колонки.Добавить("Количество",
Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));
Как проверить результат
Совпадает с количеством строк таблицы значений (или с учётом отбора)
Строк меньше — часть данных потеряна из-за типов или условий
Все ссылки заполнены, нет пустых значений
Пустые ссылки — типы колонки и реквизита не совпали
Итог по колонке совпадает с итогом исходной таблицы
Расхождение — ошибка в пересчёте или отборе строк
Типичные ошибки и как их избежать
Самая частая ошибка — ожидание, что Загрузить() сопоставит колонки по типу или по порядку. Сопоставление идёт строго по именам. Вторая распространённая ситуация — попытка загрузить в табличную часть таблицу значений с лишними колонками составного типа: это не вызывает ошибку, но затрудняет отладку.
Отдельная группа проблем — работа с объектом, который не записан. Табличную часть нового документа можно заполнять до записи, но если код обращается к данным через ссылку (ДокументСсылка.Товары), а не через объект, изменения не сохранятся. Всегда работайте через объект, полученный методом ПолучитьОбъект(), и вызывайте Записать() после заполнения.
Проверка результата перед записью
Перед записью объекта полезно выполнить несколько проверок. Сравните количество строк табличной части с количеством строк исходной таблицы значений. Пройдите по заполненным строкам и убедитесь, что обязательные реквизиты (номенклатура, количество) заполнены. Для документов с суммами сверьте итог по колонке «Сумма» с контрольной суммой источника.
Для отладки удобно вывести таблицу значений на экран методом ТЗ.ВыбратьСтроку() в толстом клиенте или выгрузить её в макет/табличный документ. На управляемых формах проще всего временно добавить реквизит формы типа «ТаблицаЗначений» и отобразить его — так видно, что именно пришло из источника до переноса.
Что важно запомнить
Загрузить() — быстрый путь при совпадающих именах колонок, но он очищает табличную часть. Цикл с Добавить() и ЗаполнитьЗначенияСвойств() — универсальный вариант для управляемых форм и различающихся структур. Всегда проверяйте типы ссылочных полей и количество строк до записи объекта.
Частые вопросы
Можно ли загрузить таблицу значений в табличную часть, не очищая существующие строки?
Метод Загрузить() всегда очищает коллекцию. Чтобы добавить строки к существующим, используйте цикл с Добавить() или выгрузите текущие данные методом Выгрузить(), объедините их с новой таблицей и загрузите результат обратно.
Почему после Загрузить() ссылочные реквизиты пустые?
Чаще всего колонка таблицы значений содержит строку или число, а реквизит ожидает ссылку. Платформа не ищет ссылку по строковому значению — нужно заранее найти ссылку запросом или методом НайтиПоКоду/НайтиПоРеквизиту и поместить её в таблицу значений с типом «СправочникСсылка».
Как заполнить табличную часть на управляемой форме, если нет метода Загрузить()?
Используйте цикл по строкам таблицы значений с добавлением строк в реквизит Объект и метод ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТЗ). Либо преобразуйте таблицу через ЗначениеВДанныеФормы, если работаете с реквизитом формы напрямую.
Что делать, если имена колонок не совпадают с реквизитами?
Три варианта: задать псевдонимы в запросе (КАК Номенклатура), переименовать колонки таблицы значений перед загрузкой или использовать построчное заполнение с явным присвоением каждого реквизита.
Как перенести только часть строк по условию?
Используйте метод НайтиСтроки() с структурой отбора или скопируйте таблицу методом Скопировать() с параметрами отбора, а затем загрузите отфильтрованный результат. При построчном заполнении просто добавьте проверку условия внутри цикла.
Нужно ли записывать объект сразу после заполнения табличной части?
Если заполнение выполняется на форме интерактивно — нет, пользователь запишет сам. Если код выполняется в фоновой процедуре или обработке, вызовите Записать() явно, иначе все изменения останутся только в памяти и будут потеряны.