При разработке правил обмена в конфигурации «Конвертация данных 2.0» часто возникает задача сопоставить объект приемника со специфической логикой. Например, когда объект передается через структуру ВходящиеДанные, а в базе-приемнике уже существуют аналогичные элементы, но с отличающимися реквизитами (например, наименование в приемнике записано без суффикса). В таком случае требуется найти существующий элемент, изменить его наименование в соответствии с источником и связать с подчиненными объектами.
Разберем детально, как работают флаги сопоставления в правилах конвертации объектов (ПКО), как устроен вызов обработчика ПоляПоиска и как программно переопределить алгоритм сопоставления.
В настройках ПКО на вкладке «Настройки поиска» ключевую роль играют флаги сопоставления. Рассмотрим варианты их поведения:
ПоляПоиска выполняются всегда. Если соответствие не найдено, создается новый объект.Таким образом, когда данные для объекта передаются вручную через ВходящиеДанные и у него нет прямого соответствия по GUID источника, флаг поиска по идентификатору необходимо снять. Это гарантирует вызов механизма поиска по полям.
Обработчик событий ПоляПоиска выполняется на стороне базы-приемника перед непосредственным поиском объекта. В нем доступны предопределенные переменные:
СвойстваПоиска — структура, содержащая значения реквизитов, переданных из источника для поиска.СсылкаНаОбъект — переменная, в которую разработчик может вручную передать найденную ссылку (тип СправочникСсылка... или ДокументСсылка...).ПрекратитьПоиск — булевый флаг. При установке значения Истина стандартный механизм сопоставления прерывается, и КД берет значение из переменной СсылкаНаОбъект.СтрокаСвойствПоиска — строка, в которой через запятую можно перечислить имена свойств поиска для стандартного алгоритма.Посмотрим на пример реализации собственного поиска. Предположим, во входящих данных наименование содержит суффикс "(головное предприятие)", а в базе-приемнике элемент записан без него. Напишем код поиска в обработчике ПоляПоиска:
// Очищаем переданное наименование от суффикса для поиска в приемнике
ИскомоеНаименование = СтрЗаменить(СвойстваПоиска.Наименование, " (головное предприятие)", "");
ИскомоеНаименование = СокрЛП(ИскомоеНаименование);
// Выполняем поиск по очищенному значению
НайденнаяСсылка = Справочники.Партнеры.НайтиПоНаименованию(ИскомоеНаименование, Истина);
Если ЗначениеЗаполнено(НайденнаяСсылка) Тогда
СсылкаНаОбъект = НайденнаяСсылка;
ПрекратитьПоиск = Истина;
Иначе
// Если по очищенному имени не найден, пробуем найти по точному совпадению
НайденнаяСсылка = Справочники.Партнеры.НайтиПоНаименованию(СвойстваПоиска.Наименование, Истина);
Если ЗначениеЗаполнено(НайденнаяСсылка) Тогда
СсылкаНаОбъект = НайденнаяСсылка;
ПрекратитьПоиск = Истина;
КонецЕсли;
КонецЕсли;
После того как объект успешно найден в базе-приемнике, встает вопрос обновления его наименования (добавления суффикса). Для этого можно применить один из двух подходов:
Наименование не стоит признак запрета перезаписи, платформа автоматически применит новое значение наименования (с суффиксом) к найденному объекту и запишет его при загрузке.ПриЗагрузке ПКО. В этом событии доступен объект базы-приемника через переменную Объект. Метод Объект.Записать() вызывать не требуется, так как запись выполняется конвейером загрузки КД:
Если Не Объект.ЭтоНовый() Тогда
Если Найти(Объект.Наименование, "(головное предприятие)") = 0 Тогда
Объект.Наименование = СокрЛП(Объект.Наименование) + " (головное предприятие)";
КонецЕсли;
КонецЕсли;
Разберем важные технические моменты, которые необходимо учитывать при работе с полями поиска:
НайтиПоНаименованию() чувствителен к длине строки и пробелам. Если в базе-приемнике возможны расхождения в спецсимволах или лишние пробелы, надежнее выполнять поиск через объект Запрос.ИНН и КПП в структуре СвойстваПоиска.