При настройке обмена через конфигурацию 1С:Конвертация данных 3.0 (формат EnterpriseData) нередко возникает задача нормализации данных. Например, в информационной базе-источнике ведется учет по нескольким служебным валютам (USD, usd+3%, usd+5%), а в базе-приемнике требуется свести все эти элементы к одной стандартной валюте USD, чтобы в документах, договорах и регистрах ссылка вела на единый элемент.
Разберем, на какой стороне (в базе-источнике или в базе-приемнике) правильнее производить объединение и какие обработчики событий правил конвертации объектов (ПКО) необходимо использовать.
Прежде чем перейти к алгоритмам, проанализируем архитектурную особенность формата EnterpriseData. В отличие от правил КД 2.0, в КД 3.0 данные передаются через объекты XDTO. При выгрузке ссылочных реквизитов (например, валюты в договоре или документе) объект передается не целиком, а в виде структуры КлючевыеСвойства.
Поэтому при обработке входящего пакета XDTO структура может выглядеть по-разному:
ДанныеXDTO.Наименование, ДанныеXDTO.Код.ДанныеXDTO.КлючевыеСвойства.Наименование, ДанныеXDTO.КлючевыеСвойства.Код.Рассмотрим сценарий, когда правила выгрузки источника остаются типовыми, а логика подмены настраивается на стороне загрузки.
Разберем по шагам реализацию в обработчике ПКО_Справочник_Валюты_ПриКонвертацииДанныхXDTO (или в обработчике получения ключевых свойств):
Посмотрим на пример программного кода:
ТекНаименование = "";
Если ДанныеXDTO.Свойство("Наименование") Тогда
ТекНаименование = ДанныеXDTO.Наименование;
ИначеЕсли ДанныеXDTO.Свойство("КлючевыеСвойства") И ДанныеXDTO.КлючевыеСвойства.Свойство("Наименование") Тогда
ТекНаименование = ДанныеXDTO.КлючевыеСвойства.Наименование;
КонецЕсли;
Если СтрНайти(НРег(ТекНаименование), "usd") = 1 Тогда
// Приводим все вариации к эталонному наименованию
Если ДанныеXDTO.Свойство("Наименование") Тогда
ДанныеXDTO.Наименование = "USD";
КонецЕсли;
Если ДанныеXDTO.Свойство("КлючевыеСвойства") Тогда
ДанныеXDTO.КлючевыеСвойства.Наименование = "USD";
ДанныеXDTO.КлючевыеСвойства.Код = "840";
КонецЕсли;
КонецЕсли;
Если в базе-приемнике для валюты настроен поиск по наименованию или коду, подсистема БСП найдет существующую эталонную валюту USD и запишет ее в сопоставление (регистр сведений СоответствияОбъектовИнформационныхБаз или ПубличныеИдентификаторыСинхронизируемыхОбъектов).
Выясним альтернативный вариант: сформировать корректное описание валюты еще на этапе выгрузки из исходной базы. Это позволяет оставить правила базы-приемника типовыми.
В правиле конвертации объекта для справочника «Валюты» в обработчике ПКО_Справочник_Валюты_ПриОтправкеДанных настраиваем алгоритм нормализации:
ТекНаименование = ДанныеИБ.Наименование;
Если СтрНайти(НРег(ТекНаименование), "usd") = 1 Тогда
ТекНаименование = "USD";
КодВалюты = "840";
Иначе
КодВалюты = ДанныеИБ.Код;
КонецЕсли;
ДанныеXDTO.Вставить("Наименование", ТекНаименование);
ДанныеXDTO.Вставить("Код", КодВалюты);
Если требуется подменять валюту непосредственно в выгружаемых документах и договорах, в соответствующих ПКО перед заполнением реквизита ссылки проверяем значение и подставляем ссылку на эталонный элемент справочника валют.
При объединении нескольких элементов в один важно учитывать следующие технические особенности:
СоответствияОбъектовИнформационныхБаз (или ПубличныеИдентификаторыСинхронизируемыхОбъектов) для ошибочных элементов и заменить ссылки в документах обработкой «Поиск и замена дублей».ПКО_Справочник_Валюты_ПередЗаписьюПолученныхДанных рекомендуется отменять запись, если объект уже найден в базе:
Если ДанныеИБ <> Неопределено Тогда
// Объект существует, предотвращаем перезапись его свойств данными из пакета
ПолученныеДанные = Неопределено;
КонецЕсли;