Как выгрузить несколько табличных частей в одну и добавить аналитику в Конвертации данных 2.0

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

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

Постановка задачи

Представим ситуацию: в документе источника есть три табличные части. Нам нужно объединить их в одну ТЧ приемника. При этом, если сумма строк ТЧ источника составляет, например, 300 рублей, в приемнике должны появиться не только эти строки, но и дополнительная корректирующая строка на ту же сумму с определенной аналитикой, задаваемой в базе-приемнике.

Решение через программное формирование коллекции объектов

Для реализации такой логики мы не будем использовать стандартное сопоставление табличных частей. Вместо этого мы создадим ПКГС (Правило конвертации группы свойств) для табличной части приемника и программно подготовим данные.

Разберем алгоритм действий по шагам:

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

Рассмотрим пример кода в обработчике ПередОбработкой (ПКГС):


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

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

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

Важный нюанс: Чтобы КД 2.0 поняла, что нужно использовать именно эту таблицу, мы присваиваем ее переменной КоллекцияОбъектов. Имена колонок должны строго совпадать с именами ПКС внутри этого ПКГС.

Передача данных через параметры для обработки в приемнике

Если аналитика (например, предопределенный элемент справочника) существует только в базе-приемнике, ее лучше заполнять на стороне загрузки. Однако, чтобы база-приемник "узнала", какие именно строки нужно дозаполнить, мы можем передать дополнительные признаки через параметры.

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

На стороне источника: Сериализуйте данные в строку или используйте ДополнительныеСвойства объекта.


// Пример передачи признака необходимости дозаполнения
Параметры.Вставить("ТребуетсяОбработкаАналитики", Истина);

Обработка данных при загрузке (событие ПослеЗагрузки)

Когда объект уже создан в памяти приемника, но еще не записан в базу, наступает идеальный момент для финальной правки данных. Используем обработчик ПослеЗагрузки в ПКО документа.

Рассмотрим пример алгоритма дозаполнения аналитики из регистра настроек приемника:


Если ПараметрыОбъекта <> Неопределено И ПараметрыОбъекта.Свойство("ТребуетсяОбработкаАналитики") Тогда
    // Обрабатываем табличную часть
    Для Каждого СтрокаТЧ Из Объект.ИмяТабличнойЧасти Цикл
        // Допустим, мы ищем строки с пустой номенклатурой, которые добавили программно
        Если Не ЗначениеЗаполнено(СтрокаТЧ.Номенклатура) Тогда
            // Ищем значение в регистре сведений приемника
            Запрос = Новый Запрос;
            Запрос.Текст = "ВЫБРАТЬ Значение ИЗ РегистрСведений.НастройкиОбмена ГДЕ Ключ = &Ключ";
            Запрос.УстановитьПараметр("Ключ", "ДефолтнаяНоменклатура");
            Выборка = Запрос.Выполнить().Выбрать();
            
            Если Выборка.Следующий() Тогда
                СтрокаТЧ.Номенклатура = Выборка.Значение;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
КонецЕсли;

Использование механизма "Входящие данные"

Еще один профессиональный способ — использование переменной ВходящиеДанные. Если вы формируете структуру в ПВД (Правиле выгрузки данных) или в родительском ПКО, вы можете передать эту структуру в подчиненное ПКГС. В настройках ПКС табличной части при этом нужно установить флаг "Получить из входящих данных". Это позволяет избежать ручного поиска объектов и делает код чище.

Советы по оптимизации

Проанализируем несколько важных моментов, которые помогут избежать ошибок при сложных трансформациях ТЧ:

  1. Поиск по имени: Если вам нужно передать предопределенный элемент, в источнике в колонку ТЗ можно записать просто его наименование (строкой). В ПКО для этой аналитики настройте поиск по наименованию. Это проще, чем лезть в базу-приемник через COM-соединение или сложные запросы при загрузке.
  2. Сериализация ТЗ: Если вам жизненно необходимо передать именно Таблицу Значений через параметры, используйте ЗначениеВСтрокуВнутр(ВашаТЗ) на источнике и ЗначениеИзСтрокиВнутр(Параметры.ВашаТЗ) на приемнике.
  3. Глобальные настройки: Если данных из регистра настроек много, не делайте запрос к базе в цикле по строкам ТЧ. Лучше один раз прочитать настройки в событии ПередЗагрузкойДанных всей конвертации и поместить их в глобальный кэш (структуру Параметры).

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

← На главную