В процессе настройки обмена данными между конфигурациями на базе 1С:Предприятие 8.3 (например, 1С:Комплексная автоматизация 2.5) часто возникает задача трансформации данных. Классический пример: в базе-источнике менеджеры создают Заказ клиента, а в базе-приемнике этот объект должен превратиться в Заказ на производство. Рассмотрим подробно, как реализовать такую логику, и разберем, почему стандартные правила регистрации здесь не помогут.
Для начала проанализируем фундаментальную разницу между механизмами обмена, чтобы не тратить время на поиск решения там, где его нет. Процесс обмена состоит из двух независимых этапов:
Заказ клиента изменен и должен быть отправлен в очередь.Таким образом, если мы хотим, чтобы Заказ клиента стал Заказом на производство, нам нужно работать именно с логикой конвертации, а не регистрации. Попытка изменить тип объекта в правилах регистрации не даст результата, так как они работают только с типами метаданных текущей базы.
В современных конфигурациях, использующих Enterprise Data (КД 3.0), вся логика преобразования сосредоточена в общем модуле МенеджерОбменаЧерезУниверсальныйФормат. Если вы используете синхронизацию через пункт "Другая программа", система обращается именно к этому модулю.
Рассмотрим алгоритм действий для изменения типа документа на стороне источника:
Выясним, в какой XDTO-тип выгружается ваш документ. Обычно Заказ клиента выгружается в формат Документ.ЗаказКлиента. Наша задача — заставить систему при выгрузке этого документа использовать структуру Документ.ЗаказНаПроизводство. Для этого в менеджере обмена в процедуре ПриВыгрузкеДанных или соответствующих обработчиках ПВД (Правил выгрузки данных) необходимо переопределить логику.
Посмотрим на пример логики, которую можно внедрить в менеджер обмена (в расширении или через модификацию модуля):
Процедура ПКС_Выгрузка_ЗаказКлиента_В_ЗаказНаПроизводство(ДанныеИБ, ДанныеXDTO, КомпонентыОбмена)
// ДанныеИБ - это наш ЗаказКлиента (ссылка или объект)
// ДанныеXDTO - структура, которая будет отправлена
// Переопределяем заполнение ТЧ и реквизитов
ДанныеXDTO.Номер = ДанныеИБ.Номер;
ДанныеXDTO.Дата = ДанныеИБ.Дата;
// Заполняем табличную часть товары как материалы или продукцию
Для Каждого СтрокаТовары Из ДанныеИБ.Товары Цикл
НоваяСтрока = ДанныеXDTO.Продукция.Добавить();
НоваяСтрока.Номенклатура = СтрокаТовары.Номенклатура;
НоваяСтрока.Количество = СтрокаТовары.Количество;
КонецЦикла;
КонецПроцедуры
Если вы не хотите глубоко внедряться в механизмы Enterprise Data, можно использовать метод "перехвата" при загрузке. Это особенно актуально, когда обе базы идентичны, и вы хотите использовать типовой механизм выгрузки Заказ клиента -> Заказ клиента, но в финале получить другой документ.
Проанализируем ситуацию: когда объект загружается в приемник, срабатывает событие записи. Мы можем создать подписку на событие ПередЗаписью для документа ЗаказКлиента. В обработчике мы отменим запись заказа клиента и вместо него создадим заказ на производство.
Рассмотрим пример реализации такого обработчика:
Процедура ПередЗаписьюЗаказаКлиентаДляКонвертации(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
// Проверяем, что запись идет из обмена данными
Если Источник.ОбменДанными.Загрузка Тогда
// Блокируем запись "пустого" или ненужного Заказа клиента
Отказ = Истина;
// Пытаемся найти уже созданный ранее Заказ на производство по уникальному идентификатору
УИД = Источник.Ссылка.УникальныйИдентификатор();
ЗаказПроизводствоСсылка = Документы.ЗаказНаПроизводство.ПолучитьСсылку(УИД);
Если ЗаказПроизводствоСсылка.ПолучитьОбъект() = Неопределено Тогда
НовыйЗаказ = Документы.ЗаказНаПроизводство.СоздатьДокумент();
НовыйЗаказ.УстановитьСсылкуНового(ЗаказПроизводствоСсылка);
Иначе
НовыйЗаказ = ЗаказПроизводствоСсылка.ПолучитьОбъект();
КонецЕсли;
// Заполняем реквизиты из Источника (Заказа клиента)
ЗаполнитьЗначенияСвойств(НовыйЗаказ, Источник, "Дата, Номер, Организация, Подразделение");
// Копируем табличные части
НовыйЗаказ.Товары.Загрузить(Источник.Товары.Выгрузить());
Попытка
НовыйЗаказ.Записать(РежимЗаписи);
Исключение
ЗаписьЖурналаРегистрации("ОбменДанными", УровеньЖурналаРегистрации.Ошибка, , , "Ошибка создания заказа на производство: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецПроцедуры
Важный момент: При использовании этого метода необходимо следить за соответствием Уникальных Идентификаторов (GUID). Если вы создаете новый объект с тем же GUID, что был у исходного документа, вы обеспечите корректную синхронизацию при повторных выгрузках (объект будет обновляться, а не дублироваться).
Для корректного и надежного решения задачи рекомендуется использовать специализированный инструмент. Выясним последовательность действий в КД 3.0:
Документ.ЗаказКлиента, а приемником — XDTO-тип, соответствующий Заказу на производство (либо напрямую Документ.ЗаказНаПроизводство в терминах вашей синхронизации).Склад в заказе клиента может соответствовать полю СкладПолучатель в заказе на производство.Вернемся к вопросу пользователя о ПР. Чтобы Заказ клиента вообще попал в выгрузку, в правилах регистрации обязательно должно быть создано правило именно для Заказа клиента. Если вы удалите его и создадите правило для Заказа на производство, система будет искать в базе-источнике именно производственные заказы. Так как их там нет (или это не те данные), обмен будет пустым.
Резюмируем:
Заказ клиента.Заказ клиента преобразуется в Заказ на производство.Чтобы убедиться, что всё работает правильно, выполним следующие шаги:
МенеджерОбменаЧерезУниверсальныйФормат в процедуре ЗагрузитьДанныеXDTO или в созданном обработчике подписки на событие.ДанныеXDTO. Мы увидим, какие поля заполнены и корректно ли прошел маппинг типов.Использование менеджера обмена — самый гибкий путь, позволяющий реализовать даже сложную трансформацию данных, включая поиск существующих объектов по дополнительным полям и обработку табличных частей со сложной логикой пересчета.