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

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

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

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

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

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

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

Где задаётся структура табличной части

Прежде чем писать код, убедитесь, что табличная часть существует в метаданных. Откройте конфигуратор, найдите нужный документ или справочник, перейдите на вкладку «Данные» и проверьте раздел «Табличные части». Там же задаются реквизиты (колонки) с типами: ссылка на номенклатуру, число для количества и цены и так далее.

Программно добавить новую колонку в табличную часть типового объекта нельзя — состав реквизитов фиксирован метаданными. Если конфигурация на поддержке, изменение структуры снимет объект с поддержки, что усложнит обновления. Безопасная альтернатива — дополнительные реквизиты и сведения (механизм БСП) или хранение данных в отдельном регистре сведений.

Базовый код: заполнение табличной части документа

Типовой сценарий — создать новый документ и добавить строки. Работа ведётся с объектом, а не со ссылкой: ссылка не позволяет изменять данные.

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

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

НовыйДок.Контрагент = Контрагент;

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

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

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

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

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

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

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

bsl
СтрокаТЧ = Объект.Товары.Добавить();
СтрокаТЧ.Номенклатура = Справочники.Номенклатура.НайтиПоКоду("000001");
Объект.Записать();

Заполнение существующего документа и очистка строк

Если документ уже существует, получают объект по ссылке, при необходимости очищают табличную часть и добавляют строки заново. Метод Очистить() удаляет все строки без возможности отката — после записи восстановить их можно только из резервной копии.

ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект();

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

Для Каждого СтрокаДанных Из ДанныеДляЗагрузки Цикл

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

НоваяСтрока.Номенклатура = СтрокаДанных.Номенклатура;

НоваяСтрока.Количество = СтрокаДанных.Количество;

КонецЦикла;

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

Для удаления части строк используйте Удалить(Строка) или перебор с конца коллекции. Удалять строки в прямом цикле «Для Каждого» нельзя — коллекция меняется во время обхода, что приводит к пропуску строк или ошибке.

Типичные ошибки
01
Изменение табличной части через ссылку вместо ПолучитьОбъект() — изменения не сохраняются или код падает с ошибкой
02
Удаление строк в цикле 'Для Каждого' — часть строк пропускается; удаляйте с конца или соберите строки в массив
03
Забытый Записать() после заполнения — строки видны только в памяти и теряются
04
Проведение без заполнения обязательных реквизитов — документ не проводится, ошибка видна только в журнале

Табличная часть справочника и особенности контекста

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

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

Копирование строк между документами

Частая задача — создать документ на основании другого со всеми строками. Прямое присваивание коллекций не работает; строки переносятся перебором или через выгрузку в таблицу значений.

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

ТЗТовары = Источник.Товары.Выгрузить();

НовыйДок.Товары.Загрузить(ТЗТовары);

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

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

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

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

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

Выгрузить() / Загрузить()

Быстрый перенос всех строк, но требует идентичного состава колонок и не позволяет трансформировать данные

ТаблицаЗначений

Свободная структура, создаётся полностью программно; подходит для промежуточных расчётов, но не хранится в базе без привязки к объекту

Динамическая таблица значений как альтернатива

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

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

ТЗ.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));

ТЗ.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));

Строка = ТЗ.Добавить();

Строка.Номенклатура = Номенклатура;

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

Это единственный способ полностью «с нуля» создать табличную структуру кодом. Но помните: таблица значений живёт только в памяти сеанса, для хранения данных её нужно загрузить в табличную часть объекта, регистр или сохранить через хранилище значения.

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

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

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

Объект.Товары.Количество() равно числу загруженных строк

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

Строк меньше — проверяйте исключения в цикле и обязательные реквизиты

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

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

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

Ошибка проверки заполнения — не заполнены обязательные поля шапки или строк

Данные в базе
Норма

После повторного открытия документа строки на месте

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

Строки пропали — не был вызван Записать() или работа шла с копией объекта

Частые ошибки и ограничения

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

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

Итог

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

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

FAQ

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

Нет, состав реквизитов табличной части определяется метаданными и меняется только в конфигураторе или через расширение конфигурации. Для произвольных колонок в рантайме используйте ТаблицаЗначений.

Почему после Добавить() строки не сохраняются?

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

Как удалить только часть строк табличной части?

Соберите подлежащие удалению строки в массив в первом цикле, затем удаляйте их методом Удалить() во втором проходе, либо перебирайте коллекцию по индексу с конца к началу.

Чем табличная часть отличается от таблицы значений?

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

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

На клиенте доступно добавление строк в Объект.Товары через Добавить(), но обращения к базе (поиск номенклатуры, запись) выполняйте в серверной процедуре формы, передавая туда нужные данные.

Безопасно ли очищать табличную часть методом Очистить()?

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