Как исправить ошибку «Переменная не определена (Источник)» в обработчике «Поля поиска» в Конвертации данных?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При настройке нестандартного поиска объектов в конфигурации «Конвертация данных 2.1» (КД) разработчики нередко сталкиваются с ошибкой компиляции: Переменная не определена (Источник) в обработчике «Последовательность полей поиска» (или «Поля поиска»). Проанализируем, почему возникает данная ситуация, как устроена среда выполнения обработчиков поиска и каким образом корректно сопоставить элементы (например, номенклатуру по данным регистра сведений ЕГАИС).

Выясним причину возникновения ошибки

Для понимания корня проблемы разберем общую архитектуру обмена данными через универсальный формат XML:

  1. Этап выгрузки (база-источник): здесь считываются объекты конфигурации. В обработчиках выгрузки («Перед выгрузкой», «При выгрузке») доступен объект Источник, откуда можно получить ссылки, реквизиты или движения регистров.
  2. Файл выгрузки: содержит только сериализованные данные (значения реквизитов, таблицы, параметры), но не содержит живых ссылок на объекты базы-источника.
  3. Этап загрузки (база-приемник): обработка «Универсальный обмен данными XML» читает файл и ищет аналогичные объекты в базе-приемнике.

Событие «Поля поиска» (в модулях обмена оно называется ПоследовательностьПолейПоиска) выполняется исключительно на этапе загрузки данных в базе-приемнике. В этот момент базы-источника уже не существует в контексте выполнения: доступен только прочитанный XML-пакет. Именно поэтому обращение к переменной Источник или Источник.Ссылка приводит к аварийной остановке с ошибкой неопределенной переменной.

Параметры, доступные в обработчике «Поля поиска»

Посмотрим на переменные среды, которые платформа КД 2.1 предоставляет разработчику в данном обработчике:

  1. СвойстваПоиска — коллекция типа Соответствие, в которой содержатся реквизиты, помеченные в правилах конвертации свойств (ПКС) флажком «Поиск объекта при загрузке по данному свойству». Получить значение реквизита можно через обращение по ключу: СвойстваПоиска["ИмяСвойства"] или СвойстваПоиска.Получить("ИмяСвойства").
  2. ПараметрыОбъекта — коллекция типа Соответствие (или значение Неопределено), содержащая переданные из источника произвольные параметры, для которых был также взведен флаг поиска.
  3. СсылкаНаОбъект — переменная, в которую разработчик должен записать найденную ссылку (например, результат поиска запросом).
  4. ПрекратитьПоиск — булевый флаг. При установке в значение Истина штатный алгоритм поиска прекращает дальнейшие попытки найти объект по другим полям.
  5. НомерВариантаПоиска — числовой номер попытки поиска (от 1 до 10). Позволяет организовывать каскадный поиск.

Пошаговое решение: поиск номенклатуры по коду ЕГАИС

Рассмотрим конкретную задачу: сопоставить номенклатуру двух баз, когда стандартный поиск по коду или наименованию не подходит, но в обеих базах ведется регистр сведений СоответствиеНоменклатурыЕГАИС.

Для реализации такого сопоставления разделим процесс на два шага: выгрузку поискового параметра из источника и обработку поиска в приемнике.

Шаг 1. Передача поискового реквизита из базы-источника

Чтобы код ЕГАИС стал доступен в базе-приемнике, настроим передачу дополнительного параметра в правиле конвертации объектов (ПКО) Номенклатура:

  1. Откроем ПКО нужного справочника. На вкладке «Настройки выгрузки» или в таблице ПКС добавим новую строку.
  2. Приемник оставим пустым, а в качестве имени укажем понятный идентификатор свойства, например КодЕГАИС.
  3. Установим флаг «Передавать данные в параметр».
  4. Обязательно включим для этой строки флаг «Поиск объекта при загрузке по данному свойству». Без этого флага переданный параметр не попадет в коллекцию ПараметрыОбъекта обработчика поиска.
  5. В обработчике «Перед выгрузкой» этого свойства напишем код для извлечения кода алкогольной продукции из регистра источника:

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |    ЕГАИС.АлкогольнаяПродукция.Код КАК Код
    |ИЗ
    |    РегистрСведений.СоответствиеНоменклатурыЕГАИС КАК ЕГАИС
    |ГДЕ
    |    ЕГАИС.Номенклатура = &Номенклатура";

Запрос.УстановитьПараметр("Номенклатура", Источник.Ссылка);
Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда
    Значение = Выборка.Код;
Иначе
    Значение = "";
КонецЕсли;

Шаг 2. Написание алгоритма в обработчике «Поля поиска»

Теперь перейдем в ПКО номенклатуры, откроем обработчик «Поля поиска» и напишем сопоставление на стороне приемника с использованием полученного параметра:


Если НомерВариантаПоиска = 1 Тогда

    // Обязательно проверяем коллекцию параметров на инициализацию
    Если ПараметрыОбъекта <> Неопределено Тогда
        КодЕГАИС = ПараметрыОбъекта.Получить("КодЕГАИС");

        Если ЗначениеЗаполнено(КодЕГАИС) Тогда
            Запрос = Новый Запрос;
            Запрос.Текст = 
                "ВЫБРАТЬ ПЕРВЫЕ 1
                |    Соответствие.Номенклатура КАК Номенклатура
                |ИЗ
                |    РегистрСведений.СоответствиеНоменклатурыЕГАИС КАК Соответствие
                |ГДЕ
                |    Соответствие.АлкогольнаяПродукция.Код = &Код
                |    И НЕ Соответствие.Номенклатура.ЭтоГруппа";

            Запрос.УстановитьПараметр("Код", КодЕГАИС);
            Выборка = Запрос.Выполнить().Выбрать();

            Если Выборка.Следующий() Тогда
                СсылкаНаОбъект = Выборка.Номенклатура;
                ПрекратитьПоиск = Истина;
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;

КонецЕсли;

Важные нюансы и типичные ошибки

Разберем несколько важных моментов, которые уберегут правила обмена от сбоев:

  1. Проверка на Неопределено: если объект переносится как ссылочный реквизит без выгрузки состава свойств, переменная ПараметрыОбъекта может быть не инициализирована. Прямое обращение ПараметрыОбъекта["КодЕГАИС"] в таком случае вызовет ошибку. Всегда используйте предварительную проверку: Если ПараметрыОбъекта <> Неопределено Тогда.
  2. Поиск по уникальному идентификатору (GUID): если в ПКО стоит флаг «Искать объект приемника по внутреннему идентификатору», то система сначала ищет элемент по GUID. Чтобы управление вообще дошло до обработчика «Поля поиска» в случае отсутствия объекта по GUID, в свойствах ПКО должен быть включен флаг «Продолжить поиск по полям поиска, если по идентификатору объект приемник не найден». Если сопоставление по GUID не требуется вовсе, отключите первую опцию.
  3. Тип коллекции СвойстваПоиска: эта переменная является Соответствием, а не Структурой. Обращение через точку (например, СвойстваПоиска.Наименование) вызовет исключение, корректный синтаксис — квадратные скобки СвойстваПоиска["Наименование"].
← На главную