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