Как объединить две табличные части в одну при выгрузке через Конвертацию данных 2.1

Программист 1С v8.3 (Обычные формы) Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При настройке обмена данными между конфигурациями, например, из Управление торговлей 10.3 в Бухгалтерию предприятия 3.0, разработчики часто сталкиваются с несовпадением структур документов. Классический пример — документ Возврат товаров от покупателя. В старой редакции УТ данные разделены на две табличные части: Товары и Услуги, в то время как в современной БП 3.0 все записи должны попасть в единую таблицу Товары.

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

Почему стандартное сопоставление не работает

Когда в ПКО (Правило конвертации объектов) мы создаем два ПКГС (Правила конвертации групп свойств), направленных в одну и ту же табличную часть приемника, механизм обмена отрабатывает их последовательно. Сначала выгружаются строки из ТЧ Товары, а затем начинается обработка ТЧ Услуги. Приемник при этом очищает коллекцию перед заполнением новыми данными, в результате чего в документе остаются только те строки, которые были обработаны последними. Чтобы избежать этого, нам нужно объединить данные на этапе выгрузки из источника в одну общую коллекцию.

Использование обработчика ПКГС и КоллекцияОбъектов

Для объединения таблиц мы воспользуемся обработчиком Перед обработкой в ПКГС (Правило конвертации группы свойств). Наша задача — создать произвольную таблицу значений, наполнить ее данными из обеих исходных таблиц и передать ее в переменную КоллекцияОбъектов. Если эта переменная определена в обработчике, КД 2.1 не будет пытаться автоматически вычитывать данные из ТЧ источника, а возьмет нашу подготовленную таблицу.

Проанализируем пример реализации, который позволяет корректно собрать данные:


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

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

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

Оптимизация кода: использование методов Выгрузить и ЗаполнитьЗначенияСвойств

Разберем, как сделать код более надежным и лаконичным. Одной из частых ошибок является ручное создание колонок, где можно опечататься или создать дубликат имени колонки (что и произошло в обсуждении на форуме). Рассмотрим более профессиональный подход, исключающий такие ошибки.

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


// Создаем скелет таблицы на основе ТЧ "Товары" источника
КоллекцияОбъектов = Источник.Товары.Выгрузить(Новый Массив());

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

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

Обратите внимание на использование универсального метода ЗаполнитьЗначенияСвойств(). Он автоматически сопоставляет имена реквизитов источника и колонок нашей новой таблицы значений. Это избавляет от необходимости писать десятки строк кода вида НовСтр.Реквизит = СтрТ.Реквизит.

Важные нюансы при переносе в Бухгалтерию 3.0

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

  1. Счета учета: Для товаров это обычно счет 41.01, а для услуг счета затрат могут варьироваться (20, 26, 44). При объединении таблиц в КоллекцияОбъектов желательно программно вычислить и подставить нужные счета, иначе в приемнике документ может не провестись.
  2. Содержание: Для услуг в таблице Товары обязательно должно быть заполнено поле Содержание. В БП 3.0 это поле используется для формирования печатных форм. Если его не заполнить, в счете-фактуре или акте вместо наименования услуги может быть пустота.
  3. Тип номенклатуры: Убедитесь, что для услуг в справочнике Номенклатура установлен вид Услуга. Это критично для корректного формирования движений по регистрам в приемнике.

Использование запроса для объединения данных

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

С помощью оператора ОБЪЕДИНИТЬ ВСЕ мы можем получить готовую таблицу значений одним действием, сразу переименовав колонки, если они называются по-разному в товарах и услугах источника:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Т.Номенклатура,
    |   Т.Количество,
    |   Т.Цена,
    |   Т.Сумма
    |ИЗ
    |   Документ.ВозвратТоваровОтПокупателя.Товары КАК Т
    |ГДЕ
    |   Т.Ссылка = &Ссылка
    |
    |ОБЪЕДИНИТЬ ВСЕ
    |
    |ВЫБРАТЬ
    |   У.Номенклатура,
    |   У.Количество,
    |   У.Цена,
    |   У.Сумма
    |ИЗ
    |   Документ.ВозвратТоваровОтПокупателя.Услуги КАК У
    |ГДЕ
    |   У.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", Источник.Ссылка);
КоллекцияОбъектов = Запрос.Выполнить().Выгрузить();

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

Настройка ПКС внутри группы свойств

После того как вы написали код в обработчике ПКГС, не забудьте настроить сами правила конвертации свойств (ПКС), которые входят в эту группу. Поскольку теперь данные берутся из КоллекцияОбъектов (нашей таблицы значений), в настройках каждого ПКС (Номенклатура, Количество и т.д.) поле Источник должно быть пустым. В поле Свойство источника нужно указать точное имя колонки из вашей таблицы значений. Если имена совпадают с именами реквизитов в приемнике, Конвертация данных сопоставит их автоматически.

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

← На главную