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