Заполнение табличной части (ТЧ) — одна из самых частых задач, с которой сталкивается разработчик при автоматизации бизнес-процессов в системе «1С:Предприятие». Будь то создание документа на основании, программное формирование отчета или обработка внешних данных, нам необходимо четко понимать, какими инструментами обладает платформа для эффективного решения этой задачи. В этой статье мы подробно разберем, как наполнить табличную часть данными, проанализируем различные подходы и выясним, каких ошибок стоит избегать.
Начнем с самого распространенного и интуитивно понятного способа — последовательного добавления строк в цикле. Этот метод идеально подходит, когда данных немного или когда логика заполнения каждой строки индивидуальна и требует сложных вычислений. Рассмотрим ситуацию, когда нам нужно программно создать объект и заполнить его товары.
Для начала разберем пример правильного кода для платформы 8.3:
// Создаем новый объект документа (например, Реализация товаров)
НовыйОбъект = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
НовыйОбъект.Дата = ТекущаяДата();
// Заполняем табличную часть в цикле
Для Каждого СтрокаДанных Из МассивИнформации Цикл
// Используем метод Добавить() для создания новой строки
НоваяСтрока = НовыйОбъект.Товары.Добавить();
// Заполняем реквизиты новой строки
НоваяСтрока.Товар = СтрокаДанных.Номенклатура;
НоваяСтрока.Количество = СтрокаДанных.Количество;
НоваяСтрока.Цена = СтрокаДанных.Цена;
// Сумму можно рассчитать вручную или вызвать обработчик
НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена;
КонецЦикла;
// В самом конце, один раз, записываем объект в базу данных
НовыйОбъект.Записать();
Проанализируем этот код. Важно обратить внимание на то, что метод Добавить() возвращает ссылку на новую строку табличной части. Это позволяет нам сразу обращаться к реквизитам этой строки через точку. Также обратите внимание на вызов Записать(): мы делаем это строго вне цикла. Вызов записи внутри цикла — критическая ошибка, которая в десятки раз замедляет работу системы, так как на каждое сохранение строки инициируется отдельная транзакция в базе данных.
Если перед нами стоит задача заполнить сотни или тысячи строк, использование метода Добавить() в цикле может быть недостаточно производительным. Платформа 1С предлагает более мощный инструмент — метод Загрузить(). Рассмотрим этот способ подробнее.
Суть метода заключается в том, что мы сначала подготавливаем данные в объекте типа ТаблицаЗначений в оперативной памяти, а затем одним махом «переливаем» их в табличную часть документа или справочника. Выясним, как это реализовать на практике:
// 1. Создаем Таблицу Значений (ТЗ) с колонками, имена которых совпадают с реквизитами ТЧ
ТаблицаДляЗагрузки = Новый ТаблицаЗначений;
ТаблицаДляЗагрузки.Колонки.Добавить("Товар");
ТаблицаДляЗагрузки.Колонки.Добавить("Количество");
ТаблицаДляЗагрузки.Колонки.Добавить("Цена");
// 2. Наполняем ТЗ данными
Для Каждого Элемент Из ВнешнийИсточник Цикл
НоваяЗапись = ТаблицаДляЗагрузки.Добавить();
НоваяЗапись.Товар = Элемент.Товар;
НоваяЗапись.Количество = Элемент.Количество;
НоваяЗапись.Цена = Элемент.Цена;
КонецЦикла;
// 3. Загружаем всю таблицу в объект за одну операцию
// Внимание: метод Загрузить() сначала полностью очищает табличную часть!
НовыйОбъект.Товары.Загрузить(ТаблицаДляЗагрузки);
Этот подход не только работает быстрее, но и делает код более чистым. Однако помните о важном нюансе: имена колонок в вашей ТаблицаЗначений должны строго совпадать с именами реквизитов табличной части объекта. Если вы ошибетесь хоть в одной букве, данные по этой колонке просто не загрузятся.
Часто новички путаются, где именно нужно выполнять заполнение. Посмотрим на две принципиально разные ситуации:
Записать(), иначе данные останутся только в памяти сервера и пропадут после завершения работы процедуры.Объект. В этом случае категорически нельзя вызывать Записать(). Пользователь должен сам решить, нажимать кнопку «Провести и закрыть» или просто закрыть форму без сохранения.Разберем пример для управляемой формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если ЭтоНовыйОбъект Тогда // Проверяем, что документ только что создан
// Работаем напрямую с данными формы
Для Каждого СтрокаТекста Из СписокДляЗаполнения Цикл
НоваяСтрока = Объект.Товары.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТекста);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
В процессе обсуждения на форумах иногда всплывают команды типа НоваяСтрока или НазначитьТип. Важно понимать, что это синтаксис версии 1С 7.7. В современных версиях (8.0, 8.1, 8.2 и 8.3) эти методы не существуют. Если вы попытаетесь использовать СтрокаТабЧасти.НоваяСтрока, система выдаст ошибку: «Метод объекта не обнаружен».
Всегда используйте актуальные методы: Добавить(), Вставить() или Загрузить(). Это гарантирует стабильную работу вашей конфигурации.
Рассмотрим ситуацию, когда заполнение должно происходить при вводе «на основании». Правильнее всего будет разместить логику не в форме, а в модуле самого объекта, в процедуре ОбработкаЗаполнения. Это универсальное место, которое отрабатывает и при создании на основании, и при вызове метода Заполнить().
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
// Очищаем ТЧ перед заполнением
Товары.Очистить();
// Переносим данные из заказа в текущий объект
Для Каждого СтрокаЗаказа Из ДанныеЗаполнения.Товары Цикл
НоваяСтрока = Товары.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаЗаказа);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Использование метода ЗаполнитьЗначенияСвойств() — это еще один «лайфхак» для программиста. Он автоматически сопоставляет имена полей источника и приемника, копируя данные. Это значительно сокращает объем кода и уменьшает вероятность опечаток.
Проанализировав все способы, мы можем сформулировать основные правила работы с табличными частями:
Очистить(), если предполагается полная перезапись данных, чтобы избежать дублей.ТаблицаЗначений и метод Загрузить().Записать() внутри цикла добавления строк.ЗаполнитьЗначенияСвойств.Следуя этим правилам, вы обеспечите высокую скорость работы системы и чистоту вашего программного кода.