При настройке обмена данными между конфигурациями 1С часто возникает задача «распаковки» или «расщепления» данных: когда одной номенклатурной позиции в базе-источнике соответствует несколько справочных записей в базе-приемнике. Например, в источнике номенклатура содержит табличную часть с кодами разных организаций или контрагентов, а в приемнике требуется создать отдельный элемент справочника Номенклатура под каждую такую строку.
В этом материале мы подробнее рассмотрим, как правильно организовать выгрузку «один в несколько» в конфигурации 1С:Конвертация данных 2.1, разберем частые ошибки начинающих разработчиков и проанализируем два основных рабочих подхода.
Рассмотрим типичную ошибку при вызове функции ВыгрузитьПоПравилу(). Разработчики часто пытаются разместить цикл выгрузки в обработчике «Перед выгрузкой» конкретного Правила конвертации свойств (ПКС) — например, для свойства Код.
Проанализируем, почему этот подход не работает:
ВыгрузитьПоПравилу() внутри обработчика ПКС приводит к попытке сформировать полный узел элемента прямо в процессе записи атрибута другого элемента, что ломает структуру файла обмена.Для корректного решения задачи выгрузку необходимо выполнять либо на уровне Правила конвертации объектов (ПКО), либо на уровне Правила выгрузки данных (ПВД).
Этот способ подходит, если исходный объект попадает на выгрузку штатным путем (например, зарегистрирован в плане обмена или переносится по умолчанию в составе выборки).
Разберем алгоритм по шагам:
Номенклатура).ВходящиеДанные и передадим ее в функцию ВыгрузитьПоПравилу().Отказ = Истина;, чтобы предотвратить стандартную выгрузку самого родительского объекта-источника.Посмотрим на пример кода в обработчике «Перед выгрузкой» ПКО:
Если Источник.КодиОбміну.Количество() > 0 Тогда
Для Каждого Стр Из Источник.КодиОбміну Цикл
// Формируем структуру с данными для приемника
пВходящиеДанные = Новый Структура;
пВходящиеДанные.Вставить("Код", Стр.КодиОбміну);
пВходящиеДанные.Вставить("Наименование", Источник.Наименование);
// Вызываем выгрузку по правилу
ВыгрузитьПоПравилу(Неопределено, , пВходящиеДанные, , "Номенклатура");
КонецЦикла;
// Отменяем выгрузку исходного единого объекта-источника
Отказ = Истина;
КонецЕсли;
Обратите внимание: в качестве источника в функцию ВыгрузитьПоПравилу() передается Неопределено, а все необходимое передается через структуру пВходящиеДанные.
Более правильным с точки зрения архитектуры КД 2.1 является вынос логики разделения объекта в Правило выгрузки данных (ПВД). Это позволяет разделить выборку данных и их непосредственную конвертацию.
Выполним следующие настройки:
Номенклатура.ВыгрузитьПоПравилу().Рассмотрим пример кода в обработчике «Перед обработкой» ПВД:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование,
| ТЧ.КодиОбміну КАК Код
|ИЗ
| Справочник.Номенклатура.КодиОбміну КАК ТЧ
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
| ПО ТЧ.Ссылка = Номенклатура.Ссылка";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
пВходящиеДанные = Новый Структура;
пВходящиеДанные.Вставить("Код", Выборка.Код);
пВходящиеДанные.Вставить("Наименование", Выборка.Наименование);
// Передаем данные в ПКО Номенклатура
ВыгрузитьПоПравилу(Неопределено, , пВходящиеДанные, , "Номенклатура");
КонецЦикла;
Чтобы база-приемник корректно прочитала реквизиты, переданные через структуру ВходящиеДанные, необходимо настроить ПКС в правиле конвертации объектов:
Номенклатура.Код, Наименование) укажем пустое поле Источник.пВходящиеДанные полностью совпадают с именами свойств приемника в ПКС.Выясним причину, по которой при вызове ВыгрузитьПоПравилу() могут пропадать дублирующиеся элементы или выгружаться только первая строка.
В Конвертации данных 2.1 работает встроенный механизм кэширования выгруженных объектов. Если в процедуру ВыгрузитьПоПравилу() в качестве источника несколько раз передается ссылка на один и тот же объект, система считает, что элемент уже обработан, и пропускает повторные вызовы.
Чтобы избежать этой проблемы, используем следующие приемы:
Неопределено в параметре Источник функции ВыгрузитьПоПравилу().КлючВыгружаемыхДанных.Использование описанных подходов позволяет гибко трансформировать структуру данных при переносе между конфигурациями любой сложности.