Как заполнить табличную часть данными из таблицы значений в 1С

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

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

Метод 1: Прямой перебор в цикле с сопоставлением полей

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

Рассмотрим пример кода, где мы обходим ТаблицуЗначений и вручную назначаем значения каждой колонке новой строки табличной части:


// Очищаем табличную часть перед заполнением, если это необходимо
Объект.Товары.Очистить();

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

Преимущества этого метода: максимальная гибкость. Вы можете выполнять любые вычисления прямо «на лету». Недостаток: низкая производительность на очень больших объемах данных (десятки тысяч строк), так как каждое обращение к свойству объекта требует времени.

Метод 2: Переименование колонок и использование метода Загрузить()

Если нам нужно перенести данные максимально быстро, лучше всего использовать системный метод Загрузить(). Однако он работает корректно только тогда, когда имена колонок в ТаблицеЗначений полностью совпадают с именами реквизитов ТабличнойЧасти.

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


// Находим нужную колонку в ТЗ и меняем ей имя на имя из ТЧ
Колонка = ТЗДанных.Колонки.Найти("ТоварСсылка");
Если Колонка <> Неопределено Тогда
    Колонка.Имя = "Номенклатура";
КонецЕсли;

КолонкаКво = ТЗДанных.Колонки.Найти("Кво");
Если КолонкаКво <> Неопределено Тогда
    КолонкаКво.Имя = "Количество";
КонецЕсли;

// Теперь, когда имена совпадают, используем быстрый метод загрузки
Объект.Товары.Загрузить(ТЗДанных);

Этот способ работает в разы быстрее прямого цикла, так как платформа выполняет копирование данных на уровне оптимизированных внутренних механизмов.

Метод 3: Использование функции ЗаполнитьЗначенияСвойств

Существует «золотая середина» между первым и вторым методом — использование функции ЗаполнитьЗначенияСвойств. Она позволяет автоматически копировать данные из полей с одинаковыми именами, избавляя нас от ручного прописывания каждой строки.

Рассмотрим, как это выглядит в коде:


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

Этот подход делает код более лаконичным и устойчивым к изменениям структуры таблиц в будущем.

Важные нюансы работы на управляемых формах

Разберем важный технический момент. Если вы работаете в модуле формы, то Объект.Товары — это не совсем табличная часть, а объект типа ДанныеФормыКоллекция. У него есть свои особенности:

  1. Метод Загрузить() отсутствует у ДанныеФормыКоллекция. Он есть только у физической таблицы значений или у табличной части реального объекта (Документа, Справочника).
  2. Если вам нужно использовать именно Загрузить() на сервере в форме, необходимо сначала преобразовать данные формы в объект, заполнить его, а затем вернуть обратно.

Посмотрим на пример такой трансформации:


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

Метод 4: Частичное обновление через ЗагрузитьКолонку()

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

Проанализируем пример:


// Выгружаем одну нужную колонку в массив
МассивЦен = ТЗДанных.ВыгрузитьКолонку("НоваяЦена");

// Загружаем этот массив напрямую в нужную колонку табличной части
Объект.Товары.ЗагрузитьКолонку(МассивЦен, "Цена");

Важно помнить, что количество элементов в массиве должно строго совпадать с количеством строк в табличной части, иначе данные «разойдутся» по строкам.

Заключение и рекомендации

Выбор метода зависит от объема данных и сложности трансформации:

При использовании любого из методов всегда следите за соответствием типов данных. Например, если в ТаблицеЗначений в колонке «Количество» окажется строка, а в ТабличнойЧасти ожидается число, платформа попытается выполнить приведение типов, что в некоторых случаях может привести к обнулению данных.

← На главную