Как в Конвертации данных 2.0 настроить поиск номенклатуры по артикулу, а если он пустой — по ГУИДу?

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

При настройке обмена данными часто возникает задача реализовать сложную логику поиска объектов в базе-приемнике. Стандартный поиск по внутреннему идентификатору (ГУИД) подходит не всегда. Рассмотрим типичный сценарий: необходимо перенести справочник "Номенклатура", при этом если у товара в источнике заполнен артикул, то в приемнике его нужно найти по этому артикулу. Если же артикул пуст, поиск должен выполняться по ГУИДу, чтобы обновить существующий элемент, а не создавать дубль.

Попытка решить эту задачу "в лоб" через смену имени правила конвертации объекта (ПКО) в обработчике ПередВыгрузкой самого объекта, как правило, не приводит к успеху. Давайте разберем, почему так происходит и как правильно реализовать такой механизм.

Основная причина неудачи простого переключения ПКО заключается в том, что механизм "Конвертации данных" по умолчанию выполняет поиск по внутреннему идентификатору объекта еще до того, как сработают многие пользовательские обработчики. Этот поиск имеет наивысший приоритет. Чтобы реализовать нашу условную логику, нам нужно взять управление поиском в свои руки. Проанализируем наиболее гибкий и правильный способ решения этой задачи.

Решение: Гибкая настройка полей поиска в ПКО

Этот метод заключается в использовании одного ПКО для номенклатуры, но с программной настройкой логики поиска внутри обработчика события ПоляПоиска. Такой подход позволяет реализовать многошаговый поиск и сосредоточить всю логику в одном месте, что упрощает дальнейшую поддержку правил.

Разберем реализацию по шагам.

Шаг 1. Отключение стандартного поиска по внутреннему идентификатору

Это критически важный первый шаг. Если его не выполнить, система все равно будет в первую очередь искать объект по ГУИДу, и наш код в ПоляПоиска может не выполниться или выполниться некорректно.

  1. Откройте ваше правило конвертации объекта (ПКО) для справочника "Номенклатура".
  2. На основной форме ПКО снимите флажок "Искать объект приемника по внутреннему идентификатору".

Теперь система не будет выполнять автоматический поиск и полностью доверит эту задачу нашему коду.

Шаг 2. Передача данных для поиска через параметры

Поскольку мы отключили стандартный механизм, нам нужно как-то передать ГУИД из источника в приемник, чтобы использовать его на втором шаге нашего поиска. Также для чистоты кода передадим и артикул. Для этого используются параметры ПКО.

  1. В окне вашего ПКО "Номенклатура" перейдите на вкладку "Параметры".
  2. Создайте два новых параметра:
    • УИД: этот параметр будет хранить строковое представление ГУИДа.
    • АртикулДляПоиска: сюда будем передавать артикул из источника.
  3. Для каждого параметра нужно определить, как он будет получаться при выгрузке. Для этого напишем код в обработчике ПередВыгрузкой самого параметра. Выделите параметр "УИД" и нажмите кнопку с многоточием в колонке "Перед выгрузкой".

В открывшемся окне введите код для получения ГУИДа:


// Обработчик "ПередВыгрузкой" для параметра "УИД"
Значение = XMLСтрока(Источник.УникальныйИдентификатор());

Аналогично для параметра "АртикулДляПоиска":


// Обработчик "ПередВыгрузкой" для параметра "АртикулДляПоиска"
Значение = Источник.Артикул;

Теперь при выгрузке каждого объекта номенклатуры в XML-файл будут дополнительно выгружены эти два параметра.

Шаг 3. Реализация условного поиска в обработчике "ПоляПоиска"

Это сердце нашего решения. Вся логика будет находиться в обработчике события ПоляПоиска на основной форме ПКО.

Обработчик ПоляПоиска вызывается системой последовательно несколько раз для одного объекта, пока объект не будет найден или не закончатся варианты поиска. Номер текущей попытки передается в переменной НомерВариантаПоиска. Мы этим воспользуемся для организации двухшагового поиска.

Откройте обработчик ПоляПоиска в вашем ПКО и введите следующий код:


// Проверяем, был ли передан артикул для поиска
Если ЗначениеЗаполнено(ПараметрыОбъекта["АртикулДляПоиска"]) Тогда

    // Если артикул есть, то на первом шаге ищем по нему
    Если НомерВариантаПоиска = 1 Тогда

        // Указываем, по каким полям в приемнике искать.
        // В данном примере в приемнике артикул лежит в реквизите "Код".
        // Если имя реквизита "Артикул", то укажите его.
        СтрокаИменСвойствПоиска = "Код"; 

        // Заполняем структуру со значениями для поиска
        СвойстваПоиска.Вставить("Код", ПараметрыОбъекта["АртикулДляПоиска"]);
    
    // Если по артикулу не нашли, то на втором шаге ищем по ГУИДу
    ИначеЕсли НомерВариантаПоиска = 2 Тогда

        Попытка
            // Получаем ссылку по строковому представлению ГУИДа из параметра
            УИД = Новый УникальныйИдентификатор(ПараметрыОбъекта["УИД"]);
            НайденнаяСсылка = Справочники.Номенклатура.ПолучитьСсылку(УИД);

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

        Исключение
            // Обработка возможной ошибки преобразования строки в ГУИД
        КонецПопытки;
        
    КонецЕсли;

Иначе

    // Если артикул в источнике не был заполнен, то сразу ищем по ГУИДу
    Если НомерВариантаПоиска = 1 Тогда
        
        Попытка
            УИД = Новый УникальныйИдентификатор(ПараметрыОбъекта["УИД"]);
            НайденнаяСсылка = Справочники.Номенклатура.ПолучитьСсылку(УИД);

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

КонецЕсли;

Проанализируем этот код:

Таким образом, мы реализовали гибкую и управляемую логику поиска, которая точно соответствует поставленной задаче. Если ни один из шагов поиска не увенчается успехом, система создаст новый объект, как и положено.

← На главную