При разработке механизмов заполнения документов на основании других объектов или при программном создании документов программисты часто сталкиваются с необходимостью перенести список значений (например, массив ссылок на номенклатуру) в табличную часть. Одним из инструментов, который кажется наиболее подходящим для этой задачи, является метод ЗагрузитьКолонку. Однако при его использовании новички часто обнаруживают, что табличная часть остается пустой. Разберем детально, почему это происходит и как правильно решать задачу заполнения данных.
Рассмотрим ситуацию: у нас есть массив номенклатуры, полученный из формы списка, и мы пытаемся загрузить его в новый документ в процедуре ОбработкаЗаполнения. Типичный ошибочный код выглядит следующим образом:
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
// Предположим, ДанныеЗаполнения.СписокТоваров — это массив ссылок
Товары.ЗагрузитьКолонку(ДанныеЗаполнения.СписокТоваров, "Номенклатура");
КонецПроцедуры
Проанализируем причину, по которой этот код не дает результата. Главная особенность метода ЗагрузитьКолонку заключается в том, что он не добавляет новые строки в таблицу. Его задача — последовательно заменить значения в уже существующих строках указанной колонки.
Выясним, как ведет себя система в зависимости от состояния табличной части:
Таким образом, использование ЗагрузитьКолонку эффективно только тогда, когда количество строк в документе уже подготовлено или соответствует размеру массива.
Для заполнения табличной части «с нуля» самым прозрачным и надежным способом является использование цикла. Проанализируем этот подход. Мы перебираем каждый элемент массива, создаем новую строку в табличной части и присваиваем значение конкретному реквизиту.
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
// Если мы полностью управляем заполнением, отключаем стандартную обработку
СтандартнаяОбработка = Ложь;
// Проверяем наличие данных
Если ТипЗнч(ДанныеЗаполнения) = Тип("Структура") И ДанныеЗаполнения.Свойство("СписокТоваров") Тогда
Для Каждого ТекущийТовар Из ДанныеЗаполнения.СписокТоваров Цикл
// Добавляем новую строку в ТЧ "Товары"
НоваяСтрока = Товары.Добавить();
// Заполняем реквизит "Номенклатура"
НоваяСтрока.Номенклатура = ТекущийТовар;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Этот метод гарантирует, что количество строк в документе будет в точности соответствовать количеству элементов в исходном массиве. Кроме того, внутри цикла мы можем сразу заполнять и другие реквизиты, например, единицы измерения или ставки НДС, обращаясь к свойствам номенклатуры.
Если вы все же хотите использовать ЗагрузитьКолонку (например, из соображений краткости кода при работе с очень большими объемами данных), необходимо сначала синхронизировать количество строк в таблице. Посмотрим, как это реализовать:
КоличествоЭлементов = ДанныеЗаполнения.СписокТоваров.Количество();
// Устанавливаем количество строк в ТЧ равным размеру массива
Пока Товары.Количество() < КоличествоЭлементов Цикл
Товары.Добавить();
КонецЦикла;
// Теперь метод отработает корректно
Товары.ЗагрузитьКолонку(ДанныеЗаполнения.СписокТоваров, "Номенклатура");
Важный нюанс: Этот способ менее универсален, чем обычный цикл, так как он заполняет только одну колонку. Если требуется заполнение нескольких реквизитов, код станет избыточным.
Разберем еще один профессиональный подход, который часто применяется при сложной логике заполнения. Метод Загрузить (не путать с ЗагрузитьКолонку) полностью замещает содержимое табличной части данными из объекта ТаблицаЗначений. Это работает очень быстро.
Товары.Загрузить(ВременнаяТаблица).
// Пример подготовки данных через ТЗ
ТЗ_Заполнения = Новый ТаблицаЗначений;
ТЗ_Заполнения.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ТЗ_Заполнения.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));
Для Каждого Элемент Из ДанныеЗаполнения.СписокТоваров Цикл
НоваяСтрокаТЗ = ТЗ_Заполнения.Добавить();
НоваяСтрокаТЗ.Номенклатура = Элемент;
НоваяСтрокаТЗ.Количество = 1; // Установим значение по умолчанию
КонецЦикла;
// Полная замена данных в ТЧ документа
Товары.Загрузить(ТЗ_Заполнения);
Проанализируем важный аспект, касающийся использования расширений (префикс яяд_расш_ в исходном вопросе). При переопределении метода ОбработкаЗаполнения в расширении необходимо всегда помнить о параметре СтандартнаяОбработка.
Если вы планируете полностью заменить алгоритм заполнения платформы своим собственным, обязательно установите СтандартнаяОбработка = Ложь;. В противном случае, после выполнения вашего кода, платформа запустит стандартный механизм, который может очистить ваши данные или добавить лишние строки, если тип данных заполнения ей знаком.
Также стоит учитывать, что при методах Загрузить() и ЗагрузитьКолонку не вызываются обработчики событий, такие как ПриИзменении в форме. Если логика вашего документа предполагает, что при выборе номенклатуры должна автоматически подставляться цена или рассчитываться сумма, эти действия нужно выполнить программно в том же коде заполнения, обратившись к соответствующим экспортным процедурам модулей менеджера или объектов.
Для корректного переноса массива в табличную часть документа в 1С следует придерживаться следующих правил:
ЗагрузитьКолонку для пустой таблицы без предварительного добавления строк.Таблицу Значений и метод Загрузить, если данных очень много или требуется сложная предварительная подготовка данных.