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

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

Как программно заполнить табличную часть в 1С

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

Табличная часть — это коллекция строк внутри объекта 1С (документа, справочника, обработки), и программное её заполнение — одна из самых частых задач при доработке конфигураций. Типовые сценарии: заполнение товаров документа по остаткам склада, загрузка строк из другого документа-основания, заполнение по данным запроса или внешнего файла.

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

Ниже разобраны рабочие примеры кода для управляемых и обычных форм, типичные ошибки и способы проверить, что заполнение прошло корректно и не «сломало» проведение документа.

Основные методы работы с табличной частью

Табличная часть объекта в коде доступна как коллекция: Объект.Товары, где «Товары» — имя табличной части, заданное в конфигураторе. У коллекции есть стандартные методы: Добавить() — создаёт новую строку, Очистить() — удаляет все строки, Количество() — возвращает число строк, Итог("Сумма") — считает итог по числовой колонке.

Минимальный пример построчного заполнения:

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

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

НоваяСтрока.Номенклатура = НайденныйТовар;

НоваяСтрока.Количество = 5;

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

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

Важно понимать: метод Добавить() только создаёт строку, но не заполняет её автоматически. Все реквизиты, которые пользователь заполнял бы руками (единицы измерения, ставки НДС, счета учёта), в коде нужно заполнить явно, иначе документ не пройдёт проверку заполнения при записи.

Заполнение по данным запроса

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Остатки.Номенклатура КАК Номенклатура,

| Остатки.КоличествоОстаток КАК Количество

|ИЗ

| РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &Склад) КАК Остатки

|ГДЕ

| Остатки.КоличествоОстаток > 0";

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

Запрос.УстановитьПараметр("Склад", Объект.Склад);

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

Метод Загрузить() переносит данные из таблицы значений в табличную часть, сопоставляя колонки по именам. Если имя колонки в запросе не совпадает с именем реквизита табличной части, данные по этой колонке будут потеряны без ошибки — поэтому в запросе используйте псевдонимы (КАК Количество), точно повторяющие имена реквизитов.

Заполнение на клиенте и на сервере в управляемых формах

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

&НаКлиенте

Процедура ЗаполнитьПоОстаткам(Команда)

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

ПоказатьВопрос(

Новый ОписаниеОповещения("ЗаполнитьПоОстаткамЗавершение", ЭтотОбъект),

"Табличная часть будет очищена. Продолжить?",

РежимДиалогаВопрос.ДаНет);

Возврат;

КонецЕсли;

ЗаполнитьПоОстаткамНаСервере();

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

&НаСервере

Процедура ЗаполнитьПоОстаткамНаСервере()

ДокументОбъект = РеквизитФормыВЗначение("Объект");

// ... запрос и ДокументОбъект.Товары.Загрузить(...)

ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");

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

Ключевой момент — преобразование данных формы в объект через РеквизитФормыВЗначение("Объект") и обратно через ЗначениеВРеквизитФормы(). Без обратного преобразования пользователь не увидит заполненные строки на форме, хотя в объекте они будут.

Порядок действий при серверном заполнении
  1. 1
    Проверьте и очистите текущие строки табличной части
  2. 2
    Преобразуйте реквизит формы в объект на сервере
  3. 3
    Выполните запрос и загрузите результат в табличную часть
  4. 4
    Верните объект в данные формы через ЗначениеВРеквизитФормы
  5. 5
    Проверьте на форме, что строки видны и итоги пересчитаны

Заполнение через типовые процедуры конфигурации

В типовых конфигурациях (УТ, ERP, Бухгалтерия) уже есть механизмы заполнения табличных частей: по документу-основанию, по остаткам, по отбору. Их вызов предпочтительнее собственного кода, потому что типовые процедуры заполняют все служебные реквизиты — ставки НДС, счета учёта, ключи связи строк.

Например, ввод на основании программно выполняется через метод Заполнить() объекта документа:

НовыйДок = Документы.РеализацияТоваровУслуг.СоздатьДокумент();

НовыйДок.Дата = ТекущаяДатаСеанса();

НовыйДок.Заполнить(ДокументОснование); // заполнит шапку и табличные части

НовыйДок.Записать();

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

Сравнение способов заполнения

Добавить() в цикле

Подходит для построчной логики с расчётом каждой строки; медленнее на больших объёмах

Загрузить() из таблицы значений

Самый быстрый для массового заполнения из запроса; требует точного совпадения имён колонок

Типовые процедуры конфигурации

Заполняют все служебные реквизиты и устойчивы к обновлениям; доступны не для всех сценариев

Заполнение из внешних данных и обработкой

Если данные приходят из файла (Excel, CSV, табличный документ), сначала загрузите их в таблицу значений, затем перенесите в табличную часть. Для табличных документов удобен метод ПостроительЗапроса или прямой обход области:

ТаблицаДанных = Новый ТаблицаЗначений;

ТаблицаДанных.Колонки.Добавить("Артикул");

ТаблицаДанных.Колонки.Добавить("Количество");

Для Строка = 2 По ТабДок.ВысотаТаблицы Цикл

НоваяСтрока = ТаблицаДанных.Добавить();

НоваяСтрока.Артикул = ТабДок.Область(Строка, 1).Текст;

НоваяСтрока.Количество = Число(ТабДок.Область(Строка, 2).Текст);

КонецЦикла;

// далее поиск номенклатуры по артикулу и заполнение табличной части

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

Проверка результата и типичные ошибки

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

Если Объект.Товары.Количество() = 0 Тогда

Сообщить("Табличная часть не заполнена. Проверьте отбор запроса.");

КонецЕсли;

Для Каждого СтрокаТовара Из Объект.Товары Цикл

Если Не ЗначениеЗаполнено(СтрокаТовара.Номенклатура) Тогда

Сообщить("В строке " + СтрокаТовара.НомерСтроки + " не указана номенклатура");

КонецЕсли;

КонецЦикла;

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

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

Строки на форме
Норма

Строки видны, номера строк идут по порядку

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

Строки в объекте есть, но на форме не отображаются — не выполнено ЗначениеВРеквизитФормы

Итоги документа
Норма

Сумма документа совпадает с суммой по строкам

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

Итог не пересчитан — не вызваны процедуры расчёта строк

Проведение
Норма

Документ проводится без сообщений, движения корректны

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

Ошибки о незаполненных счетах, ставках НДС, складах в строках

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

Частые вопросы

Как заполнить табличную часть, не очищая существующие строки?

Используйте цикл по таблице значений с методом Добавить() вместо Загрузить(). Метод Загрузить() всегда полностью замещает содержимое табличной части, а Добавить() присоединяет новые строки к имеющимся.

Почему после Загрузить() колонка осталась пустой?

Имя колонки в источнике не совпадает с именем реквизита табличной части. Сопоставление идёт строго по именам, лишние колонки игнорируются, а несовпавшие реквизиты остаются пустыми. Задайте в запросе псевдоним через КАК, точно повторяющий имя реквизита.

Как пересчитать сумму строки после заполнения количества и цены?

Либо рассчитайте в коде (Сумма = Количество * Цена), либо вызовите типовую процедуру расчёта строки из общего модуля конфигурации — в типовых решениях она обычно называется РассчитатьСуммуСтроки или аналогично и учитывает НДС и скидки.

Можно ли заполнить табличную часть у записанного, но не проведённого документа?

Да. Получите объект через ПолучитьОбъект() по ссылке, измените табличную часть и вызовите Записать(). Для проведённого документа сначала отмените проведение (Записать с режимом отмены проведения), иначе движения не пересчитаются.

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

Выполните запрос по реквизитам документов, в цикле получайте каждый объект через Ссылка.ПолучитьОбъект(), заполняйте табличную часть и записывайте. Для больших объёмов используйте транзакции порциями и тестируйте сначала на копии базы — массовое изменение необратимо.

Итог

Что важно запомнить

Для заполнения табличной части выбирайте Загрузить() при массовом переносе из запроса и Добавить() при построчной логике. В управляемых формах работайте через серверные процедуры с преобразованием РеквизитФормыВЗначение. Всегда заполняйте служебные реквизиты строк и проверяйте результат записью и проведением документа.