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