К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как в табличную часть загрузить таблицу значений в 1С

Как загрузить таблицу значений в табличную часть документа или справочника 1С: метод Загрузить, построчное заполнение, типовые ошибки и проверка результата.

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

Метод Загрузить() работает быстрее и короче в написании, но требует совпадения структур: он копирует значения по именам колонок и игнорирует колонки, которых нет в табличной части. Построчное заполнение длиннее, зато позволяет преобразовывать значения, искать ссылки по наименованию, рассчитывать суммы и контролировать каждую строку отдельно. Ниже разобраны оба способа с рабочим кодом, ограничениями и проверкой результата.

Что такое таблица значений и табличная часть в 1С

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

Табличная часть — это подчинённая коллекция строк объекта конфигурации: документа, справочника, обработки. Её состав колонок жёстко задан в конфигураторе, и записывается она в базу только вместе с объектом-владельцем при вызове Записать(). Пока объект не записан, загруженные строки существуют только в памяти.

Понимание этой разницы важно: таблица значений — источник, табличная часть — приёмник, привязанный к объекту. Любая загрузка сводится к переносу строк из первого во второй с последующей записью объекта.

Способ 1. Загрузить таблицу значений методом Загрузить()

Самый короткий путь — метод Загрузить(). Он полностью очищает табличную часть и заполняет её строками таблицы значений. Сопоставление идёт по именам колонок: если в таблице значений есть колонка «Номенклатура» и в табличной части есть реквизит «Номенклатура», значение перенесётся.

// ДокОбъект — объект документа, ТЗ — подготовленная таблица значений

ДокОбъект.Товары.Загрузить(ТЗ);

ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);

Важные особенности метода. Во-первых, Загрузить() всегда очищает табличную часть — если нужно добавить строки к существующим, метод не подходит, используйте цикл или предварительно объедините данные в одной таблице значений. Во-вторых, лишние колонки таблицы значений молча игнорируются, а реквизиты табличной части, которым не нашлось пары, остаются пустыми. В-третьих, типы должны быть совместимы: строка «123» не попадёт в числовой реквизит без ошибки, если в колонке таблицы значений задан составной или строковый тип.

Перед загрузкой полезно привести таблицу значений к нужной структуре: переименовать колонки через ТЗ.Колонки.СтароеИмя.Имя = "НовоеИмя" или создать копию с нужным набором колонок через ТЗ.Скопировать() с отбором.

Способ 2. Построчное заполнение через цикл

Когда имена колонок не совпадают, данные нужно искать в справочниках или рассчитывать на лету — используйте цикл Для Каждого с добавлением строк вручную. Это стандартный приём при загрузке из внешних файлов, где вместо ссылок лежат наименования или коды.

ДокОбъект.Товары.Очистить();

Для Каждого СтрокаТЗ Из ТЗ Цикл

НоваяСтрока = ДокОбъект.Товары.Добавить();

НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоКоду(СтрокаТЗ.КодТовара);

НоваяСтрока.Количество = Число(СтрокаТЗ.КоличествоСтрокой);

НоваяСтрока.Цена = СтрокаТЗ.Цена;

НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена;

КонецЦикла;

ДокОбъект.Записать();

Если часть полей совпадает по именам, можно комбинировать: сначала ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТЗ), а затем вручную дозаполнить поля, требующие поиска или расчёта. Это сокращает код и снижает риск забыть какой-то реквизит.

Контролируйте, что НайтиПоКоду() или НайтиПоНаименованию() действительно вернули ссылку. Если поиск не дал результата, в строку попадёт пустая ссылка, и документ либо не проведётся, либо запишется с незаполненной аналитикой. Добавляйте проверку Если Ссылка.Пустая() Тогда ... с выводом сообщения пользователю.

Порядок действий при построчной загрузке
  1. 1
    Получите объект документа: ДокОбъект = Документы.РеализацияТоваровУслуг.СоздатьДокумент() или ПолучитьОбъект() для существующего
  2. 2
    Очистите табличную часть, если строки нужно заменить: ДокОбъект.Товары.Очистить()
  3. 3
    В цикле Для Каждого добавляйте строки и заполняйте реквизиты, включая расчёт сумм
  4. 4
    Проверьте, что ссылочные поля заполнены найденными ссылками, а не пустыми значениями
  5. 5
    Запишите объект: Записать() или Записать с проведением
  6. 6
    Проверьте результат, открыв документ в режиме предприятия

Сравнение двух способов загрузки

Выбор способа определяется структурой данных и требованиями к обработке. Ниже — сопоставление по ключевым критериям.

КритерийЗагрузить()Цикл с Добавить()
Имена колонокДолжны совпадать с реквизитамиЛюбые, сопоставление в коде
Поиск ссылок по коду/наименованиюНевозможенВыполняется в цикле
Расчёт сумм и зависимых полейОтдельно после загрузкиСразу при заполнении строки
Объём кода1–2 строкиОт 5 строк и больше
Контроль ошибок по строкамНет, ошибка типов прерывает всёМожно пропустить или залогировать строку

Сравнение вариантов

Загрузить()

Подходит, когда таблица значений получена из запроса к той же базе и структура совпадает. Ограничение: очищает табличную часть и не вызывает пересчёты.

Цикл с Добавить()

Подходит для загрузки из файлов и внешних источников, где нужны поиск ссылок и преобразования. Ограничение: больше кода и медленнее на очень больших объёмах.

ЗагрузитьКолонку()

Частный случай: переносит одну колонку таблицы значений в один реквизит существующих строк. Подходит, когда строки уже есть и нужно дозаполнить одно поле.

Загрузка в управляемой форме и на клиенте

В управляемых формах табличная часть объекта доступна как данные формы, и работа с ней разделена между клиентом и сервером. Таблицу значений нельзя передать с сервера на клиент напрямую — она несериализуема. Поэтому типовой приём: на сервере загрузить таблицу значений в реквизит объекта, а на клиенте только отобразить результат.

&НаСервере

Процедура ЗагрузитьНаСервере(ТЗ)

Объект.Товары.Загрузить(ТЗ);

КонецПроцедуры

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

После загрузки на сервере форма обновится автоматически, так как данные объекта связаны с элементами формы. Если табличная часть лежит в реквизите формы типа «ТаблицаЗначений» (динамическая коллекция), применяйте ЗначениеВРеквизитФормы() для преобразования.

При загрузке больших объёмов (десятки тысяч строк) построчный цикл с поиском ссылок по наименованию работает заметно медленно. Ускорить можно так: одним запросом получить соответствие кодов и ссылок, а в цикле брать ссылки из соответствия без обращений к базе.
ПЗ
Практическое замечание

Типичные ошибки и как их избежать

Первая и самая частая ошибка — забыть записать объект после загрузки. Метод Загрузить() меняет данные только в оперативной памяти; без Записать() табличная часть в базе останется прежней. Признак: в отладчике строки есть, а после закрытия обработки в документе пусто.

Вторая ошибка — работа с данными формы вместо объекта. Если в модуле формы вы пишете Объект.Товары.Загрузить(ТЗ), это корректно, но если берёте ссылку через реквизит и вызываете методы без ПолучитьОбъект(), загрузка не выполнится: у объекта «ДокументСсылка» нет доступа к табличной части на изменение. Сначала получите объект: ДокОбъект = Ссылка.ПолучитьОбъект().

Третья группа ошибок связана с типами. Таблица значений, выгруженная из запроса, хранит ссылки правильного типа, а таблица, прочитанная из Excel или CSV, содержит строки. Загрузка строк в ссылочные реквизиты вызовет ошибку преобразования или молчаливую запись пустых значений. Всегда преобразуйте типы явно и проверяйте результат поиска ссылок.

Типичные ошибки
01
Загрузить() без последующего Записать() — данные остаются только в памяти и теряются
02
Ожидание автоматического пересчёта сумм — обработчики ПриИзменении при программной загрузке не вызываются
03
Попытка загрузить строки из файла напрямую в ссылочные реквизиты без поиска ссылок — получаются пустые значения
04
Использование Загрузить() там, где нужно добавить строки к существующим — старые строки стираются
05
Работа со ссылкой вместо объекта — у ДокументСсылка нет доступа к табличной части на запись

Проверка результата загрузки

После записи убедитесь, что данные попали в базу корректно. Минимальный набор проверок: количество строк в табличной части совпадает с количеством строк источника, ссылочные поля заполнены, суммы посчитаны.

Если ДокОбъект.Товары.Количество() <> ТЗ.Количество() Тогда

Сообщить("Количество строк не совпадает!");

КонецЕсли;

Для массовых загрузок полезно считать контрольные итоги: сумму колонки «Сумма» в таблице значений и в загруженной табличной части. Расхождение указывает на потерянные строки или ошибки преобразования типов. Финальная проверка — открыть документ в режиме предприятия и попытаться его провести: проведение покажет незаполненные обязательные поля.

Контрольные точки

Как проверить результат

Количество строк
Норма

Совпадает с количеством строк таблицы значений-источника

Тревожный признак

Строк меньше — часть данных потеряна при преобразовании

Ссылочные поля (Номенклатура, Контрагент)
Норма

Во всех строках заполнены реальные ссылки

Тревожный признак

Пустые значения — поиск по коду или наименованию не сработал

Суммы и НДС
Норма

Рассчитаны и сходятся с контрольным итогом источника

Тревожный признак

Нули или расхождения — не выполнен пересчёт после Загрузить()

Проведение документа
Норма

Документ проводится без сообщений об ошибках

Тревожный признак

Ошибки проведения указывают на незаполненные обязательные реквизиты

FAQ

Можно ли загрузить таблицу значений в табличную часть, не очищая существующие строки?

Да, но не методом Загрузить() — он всегда очищает коллекцию. Используйте цикл с Добавить(): новые строки допишутся в конец табличной части, а существующие сохранятся. Либо выгрузите текущие строки через Выгрузить(), объедините с новыми в одной таблице значений и загрузите обратно.

Почему после Загрузить() не заполнились суммы, хотя цена и количество есть?

Программная загрузка не вызывает обработчики событий формы вроде ПриИзменении, в которых обычно прописан расчёт суммы. После загрузки пройдите по строкам циклом и рассчитайте суммы явно, либо вызовите экспортную процедуру пересчёта, если она есть в модуле объекта.

Как загрузить данные из Excel в табличную часть документа?

Общая схема: прочитать файл в таблицу значений (через COM-объект Excel, табличный документ или готовую обработку загрузки), затем в цикле найти ссылки справочников по кодам или наименованиям и заполнить табличную часть через Добавить(). Напрямую Загрузить() здесь обычно не подходит, потому что в файле лежат строки, а не ссылки.

Что делать, если имена колонок таблицы значений не совпадают с реквизитами табличной части?

Либо переименуйте колонки таблицы значений перед вызовом Загрузить() — свойство Имя у объекта колонки доступно для записи, либо заполняйте строки в цикле, явно указывая соответствие: НоваяСтрока.Товар = СтрокаТЗ.НоменклатураИзФайла.

Можно ли передать таблицу значений с сервера на клиент в управляемой форме?

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

Как загрузить только часть колонок таблицы значений?

Создайте копию таблицы с нужными колонками: ТЗ.Скопировать(, "Номенклатура,Количество,Цена") — второй параметр задаёт список колонок через запятую. Полученную таблицу загрузите методом Загрузить(). Лишние колонки исходной таблицы и так игнорируются, но явное ограничение делает код понятнее и защищает от случайного совпадения имён.