При настройке правил обмена в конфигурации «Конвертация данных» (КД 2.1) часто возникает задача дифференцированного сопоставления элементов одного и того же справочника. Типичный сценарий: юридические лица необходимо однозначно идентифицировать по реквизитам ИНН и КПП, тогда как у физических лиц КПП отсутствует, а ИНН может быть не заполнен, поэтому их требуется находить по реквизиту Наименование.
Разберем детально, как реализовать подобную логику сопоставления, какие ошибки синтаксиса и алгоритмов часто допускаются и какие альтернативные архитектурные решения существуют.
Проанализируем работу штатного механизма. В обработчике события Поля поиска (или Последовательность полей поиска) правила конвертации объекта (ПКО) можно динамически управлять переменной СтрокаИменСвойствПоиска. Именно в ней через запятую указываются имена реквизитов, по значениям которых конфигурация приемника будет выполнять поиск.
Для корректной работы алгоритма необходимо выполнить предварительную настройку состава свойств:
Наименование, ИНН, КПП, а также реквизит дифференциации типа контрагента — ФормаСобственности (или ЮрФизЛицо). Если реквизит не отмечен флагом поиска, его значение не попадет в коллекцию СвойстваПоиска в базе-приемнике.ФормыСобственности настроено соответствующее правило конвертации значений (ПКЗ) или перечисления сопоставлены, иначе в коллекции СвойстваПоиска значение ссылки будет равно Неопределено.Посмотрим на пример кода, который помещается в обработчик события Поля поиска на уровне ПКО:
Если СвойстваПоиска["ФормаСобственности"] = Перечисления.ФормыСобственности.ЧастноеЛицо Тогда
СтрокаИменСвойствПоиска = "Наименование";
ИначеЕсли ЗначениеЗаполнено(СвойстваПоиска["КПП"]) Тогда
СтрокаИменСвойствПоиска = "ИНН, КПП";
Иначе
СтрокаИменСвойствПоиска = "ИНН";
КонецЕсли;
Выясним причину частой ошибки компиляции вида Ожидается последовательность операторов, возникающей при загрузке данных. Часто при копировании кода из текстовых редакторов или форумов вставляются лишние или пропущенные конструкции КонецЕсли;. Необходимо строго следить за тем, чтобы каждая ветка Если ... Тогда закрывалась ровно один раз, а в цепочках ИначеЕсли не дублировался закрывающий оператор.
Рассмотрим важные нюансы работы обработчика Поля поиска:
Поля поиска выполняется исключительно на стороне базы-приемника во время загрузки данных. Поэтому попытки прямого обращения к объектам базы-источника через переменную Источник (например, Источник.ФормаСобственности) приведут к ошибке. Все доступные для анализа реквизиты должны читаться из структуры СвойстваПоиска.ЭтоГруппа галочкой поиска в ПКС и передавайте его в строке поиска: СтрокаИменСвойствПоиска = "ЭтоГруппа, Наименование";.ПрекратитьПоиск = Истина;.ПОДОБНО), можно сформировать прямой запрос к справочнику приемника и присвоить найденную ссылку встроенной переменной СсылкаНаОбъект. Как только эта переменная заполнена, платформа прекратит штатный поиск и сопоставит объект.Разберем альтернативный архитектурный вариант, который считается более прозрачным и простым в отладке, если логика заполнения юридических и физических лиц в приемнике существенно различается.
Контрагенты_ЮрЛица и Контрагенты_ФизЛица.Контрагенты_ЮрЛица жестко задаем флаги поиска по реквизитам ИНН и КПП, не перегружая код обработчиками.Контрагенты_ФизЛица жестко отмечаем флаг поиска только по свойству Наименование (и при необходимости ЭтоГруппа).Перед выгрузкой перенаправляем поток выгрузки на нужное правило с помощью предопределенной переменной ИмяПКО:
Если Источник.ФормаСобственности = Перечисления.ФормыСобственности.ЧастноеЛицо Тогда
ИмяПКО = "Контрагенты_ФизЛица";
Иначе
ИмяПКО = "Контрагенты_ЮрЛица";
КонецЕсли;
Такой подход полностью изолирует правила сопоставления на уровне метаданных КД, исключает необходимость писать разветвленные проверки в обработчике загрузки и снижает риск возникновения синтаксических ошибок в файле правил.