Как реализовать выгрузку одного документа из источника в несколько документов в приемнике в 1С:Конвертация данных

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

При настройке обмена данными между конфигурациями 1С часто возникает задача, когда структура данных в источнике и приемнике не совпадает линейно. Одной из самых интересных и сложных задач является реализация принципа «один ко многим». Рассмотрим классический пример: в исходной базе у нас есть документ ОтчетПереработчика, в табличной части которого указано несколько позиций сырья. В базе-приемнике бизнес-логика требует, чтобы на каждую строку этого сырья создавался отдельный документ КомплектацияНоменклатуры. В этой статье мы подробно разберем, как реализовать этот механизм с помощью конфигурации «Конвертация данных 2.0».

Принцип работы механизма «Один ко многим»

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

Разберем общую схему решения:

  1. Создаем ПКО для документа-приемника без указания источника.
  2. Настраиваем свойства в ПКО на получение из ВходящиеДанные.
  3. В ПВД пишем алгоритм, который обходит строки источника и для каждой строки вызывает выгрузку по правилу.
  4. Решаем вопрос с уникальностью (поиском) документов в приемнике.

Шаг 1. Настройка Правила конвертации объекта (ПКО)

Проанализируем настройку ПКО для документа КомплектацияНоменклатуры. Поскольку мы будем передавать данные программно, само правило не должно быть жестко привязано к объекту-источнику.

Создадим новое ПКО:

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

Шаг 2. Реализация логики в Правиле выгрузки данных (ПВД)

Теперь перейдем к самому важному этапу — программному коду в ПВД. Создадим ПВД для нашего документа ОтчетПереработчика. В поле «Способ выборки» выберем «Произвольный алгоритм». Весь код мы будем писать в обработчике Перед обработкой.

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


// Получаем объект документа-источника (он доступен в переменной Объект или через выборку)
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ОтчетПереработчикаМатериалы.Номенклатура,
    |   ОтчетПереработчикаМатериалы.Количество,
    |   ОтчетПереработчикаМатериалы.Ссылка КАК СсылкаНаИсточник
    |ИЗ
    |   Документ.ОтчетПереработчика.Материалы КАК ОтчетПереработчикаМатериалы
    |ГДЕ
    |   ОтчетПереработчикаМатериалы.Ссылка = &Источник";

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

Пока Выборка.Следующий() Цикл
    
    // Подготавливаем структуру для передачи в ПКО
    ВходящиеДанные = Новый Структура;
    ВходящиеДанные.Вставить("Номенклатура", Выборка.Номенклатура);
    ВходящиеДанные.Вставить("Количество",   Выборка.Количество);
    ВходящиеДанные.Вставить("Дата",         Выборка.СсылкаНаИсточник.Дата);
    ВходящиеДанные.Вставить("Склад",        Выборка.СсылкаНаИсточник.Склад);
    
    // Важно: генерируем ключ поиска или передаем данные для поиска
    // Чтобы не было дублей при повторной выгрузке
    ВходящиеДанные.Вставить("КлючСвязи", Выборка.СсылкаНаИсточник.Номер + "_" + Выборка.Номенклатура.Код);

    // Вызываем выгрузку по конкретному правилу (ПКО)
    ВыгрузитьПоПравилу(Неопределено, , ВходящиеДанные, , "КомплектацияНоменклатуры");

КонецЦикла;

// Отменяем стандартную выгрузку самого объекта, так как мы всё сделали вручную
Отказ = Истина;

В функции ВыгрузитьПоПравилу первым параметром мы передаем Неопределено, так как источника как такового у нас нет. Третьим параметром передается наша структура ВходящиеДанные, а последним — строковое имя ПКО, которое мы создали на первом шаге.

Шаг 3. Решение проблемы уникальности и поиска

Проанализируем ситуацию: если мы просто выгрузим данные, КД попытается создать документы. Но как система поймет при повторной выгрузке, что этот документ уже был создан? Обычно поиск идет по Уникальному Идентификатору (УИД), но у нас из одного источника получается четыре приемника. У всех них будет УИД исходного документа, что приведет к перезаписи одного и того же объекта четыре раза (в итоге останется только последний).

Рассмотрим способы решения этой проблемы:

  1. Поиск по полям: В ПКО установите галочки «Поиск» у тех реквизитов, которые в совокупности дают уникальность. Например, Дата, Склад и Номенклатура. Однако это не всегда надежно.
  2. Программная генерация УИД: Вы можете формировать уникальный идентификатор на лету, используя комбинацию УИД источника и, например, индекса строки. Это самый надежный способ для КД 2.0.
  3. Использование дополнительных реквизитов: Можно записывать в документ-приемник ссылку на источник и номер строки, а затем использовать их в обработчике ПоляПоиска.

Шаг 4. Обработка табличных частей в приемнике

Часто документ-приемник (в нашем случае КомплектацияНоменклатуры) сам имеет сложную структуру с табличными частями. Если нам нужно передать данные в ТЧ приемника из ВходящиеДанные, мы должны действовать следующим образом:

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


// Пример подготовки таблицы для ТЧ во ВходящиеДанные
ТЗ_Комплектующие = Новый ТаблицаЗначений;
ТЗ_Комплектующие.Колонки.Добавить("Номенклатура");
ТЗ_Комплектующие.Колонки.Добавить("Количество");

НоваяСтрока = ТЗ_Комплектующие.Добавить();
НоваяСтрока.Номенклатура = Выборка.Материал;
НоваяСтрока.Количество = Выборка.КоличествоМатериала;

ВходящиеДанные.Вставить("ТабличнаяЧасть_Комплектующие", ТЗ_Комплектующие);

Важные рекомендации и итоги

Выясним причину возможных ошибок при такой реализации. Чаще всего проблемы возникают из-за:

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

← На главную