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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Метод 1: Построчное добавление данных через метод Добавить()

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

Для начала разберем пример правильного кода для платформы 8.3:


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

// Заполняем табличную часть в цикле
Для Каждого СтрокаДанных Из МассивИнформации Цикл
    // Используем метод Добавить() для создания новой строки
    НоваяСтрока = НовыйОбъект.Товары.Добавить();
    
    // Заполняем реквизиты новой строки
    НоваяСтрока.Товар = СтрокаДанных.Номенклатура;
    НоваяСтрока.Количество = СтрокаДанных.Количество;
    НоваяСтрока.Цена = СтрокаДанных.Цена;
    
    // Сумму можно рассчитать вручную или вызвать обработчик
    НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена;
КонецЦикла;

// В самом конце, один раз, записываем объект в базу данных
НовыйОбъект.Записать();

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

Метод 2: Оптимизированная загрузка через метод Загрузить()

Если перед нами стоит задача заполнить сотни или тысячи строк, использование метода Добавить() в цикле может быть недостаточно производительным. Платформа 1С предлагает более мощный инструмент — метод Загрузить(). Рассмотрим этот способ подробнее.

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


// 1. Создаем Таблицу Значений (ТЗ) с колонками, имена которых совпадают с реквизитами ТЧ
ТаблицаДляЗагрузки = Новый ТаблицаЗначений;
ТаблицаДляЗагрузки.Колонки.Добавить("Товар");
ТаблицаДляЗагрузки.Колонки.Добавить("Количество");
ТаблицаДляЗагрузки.Колонки.Добавить("Цена");

// 2. Наполняем ТЗ данными
Для Каждого Элемент Из ВнешнийИсточник Цикл
    НоваяЗапись = ТаблицаДляЗагрузки.Добавить();
    НоваяЗапись.Товар = Элемент.Товар;
    НоваяЗапись.Количество = Элемент.Количество;
    НоваяЗапись.Цена = Элемент.Цена;
КонецЦикла;

// 3. Загружаем всю таблицу в объект за одну операцию
// Внимание: метод Загрузить() сначала полностью очищает табличную часть!
НовыйОбъект.Товары.Загрузить(ТаблицаДляЗагрузки);

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

Различие контекстов: Форма против Объекта

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

  1. Заполнение при программном создании (без открытия формы): Как в примерах выше, мы работаем с объектом. Здесь обязательно нужно вызвать Записать(), иначе данные останутся только в памяти сервера и пропадут после завершения работы процедуры.
  2. Заполнение при создании в форме (ПриСозданииНаСервере): Если ваша задача — заполнить документ данными при его открытии пользователем (например, подтянуть остатки), вы работаете с реквизитом Объект. В этом случае категорически нельзя вызывать Записать(). Пользователь должен сам решить, нажимать кнопку «Провести и закрыть» или просто закрыть форму без сохранения.

Разберем пример для управляемой формы:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Если ЭтоНовыйОбъект Тогда // Проверяем, что документ только что создан
        // Работаем напрямую с данными формы
        Для Каждого СтрокаТекста Из СписокДляЗаполнения Цикл
            НоваяСтрока = Объект.Товары.Добавить();
            ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТекста);
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры

Ловушка старого синтаксиса: почему не работает «НоваяСтрока»?

В процессе обсуждения на форумах иногда всплывают команды типа НоваяСтрока или НазначитьТип. Важно понимать, что это синтаксис версии 1С 7.7. В современных версиях (8.0, 8.1, 8.2 и 8.3) эти методы не существуют. Если вы попытаетесь использовать СтрокаТабЧасти.НоваяСтрока, система выдаст ошибку: «Метод объекта не обнаружен».

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

Использование стандартного механизма «ОбработкаЗаполнения»

Рассмотрим ситуацию, когда заполнение должно происходить при вводе «на основании». Правильнее всего будет разместить логику не в форме, а в модуле самого объекта, в процедуре ОбработкаЗаполнения. Это универсальное место, которое отрабатывает и при создании на основании, и при вызове метода Заполнить().


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
    Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
        // Очищаем ТЧ перед заполнением
        Товары.Очистить();
        
        // Переносим данные из заказа в текущий объект
        Для Каждого СтрокаЗаказа Из ДанныеЗаполнения.Товары Цикл
            НоваяСтрока = Товары.Добавить();
            ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаЗаказа);
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры

Использование метода ЗаполнитьЗначенияСвойств() — это еще один «лайфхак» для программиста. Он автоматически сопоставляет имена полей источника и приемника, копируя данные. Это значительно сокращает объем кода и уменьшает вероятность опечаток.

Подведем итоги и закрепим лучшие практики

Проанализировав все способы, мы можем сформулировать основные правила работы с табличными частями:

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

← На главную