Как настроить поиск по параметру в Конвертации данных 2.1 с помощью события «Поля поиска»?

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

При переносе данных между информационными базами 1С с помощью конфигурации «Конвертация данных 2.1» (КД 2.1) разработчики часто сталкиваются с нестандартными сценариями сопоставления объектов. Классический пример — перенос справочника Номенклатура. Предположим, что в базе-источнике коды номенклатуры имеют префиксы (например, «ПРФ-0000125»), а в базе-приемнике (например, «Управление производственным предприятием» или «ERP») учет ведется без префиксов (например, «00000125»).

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

Общая концепция: как устроен поиск в КД 2.1

Рассмотрим, как работает стандартный механизм поиска при загрузке данных:

  1. Поиск по уникальному идентификатору (GUID). Если в Правилах конвертации объектов (ПКО) установлен флаг «Искать по уникальному идентификатору», система в первую очередь пытается найти объект в приемнике по его GUID. Если объект найден, поиск завершается.
  2. Поиск по полям поиска. Если по GUID объект не найден (или флаг отключен), КД 2.1 переходит к анализу правил конвертации свойств (ПКС), для которых установлен флаг «Поиск». На основании этих свойств формируется поисковый запрос к базе данных. При миграции данных между близкими конфигурациями, когда объекты в базах создавались независимо и имеют разные GUID, для сопоставления по произвольным реквизитам применяют обработку для переноса данных между похожими конфигурациями 1С.
  3. Пошаговый (многовариантный) поиск. Если стандартный поиск по всем отмеченным полям сразу не дает результатов, мы можем настроить итерационный поиск в обработчике «Поля поиска» с помощью переменной НомерВариантаПоиска.

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

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

СтрокаИменСвойствПоиска = "Пар_Код"; // Ошибка!

Выясним причину, почему этот код приведет к аварийному завершению загрузки. Переменная СтрокаИменСвойствПоиска предназначена исключительно для перечисления через запятую реальных реквизитов (свойств) объекта-приемника, которые физически существуют в метаданных базы-приемника. На основе этой строки ядро КД 2.1 строит динамический запрос к СУБД.

Поскольку у справочника Номенклатура в базе-приемнике нет реквизита с именем Пар_Код, платформа выдаст ошибку о том, что поле не найдено в схеме запроса. Любой поиск по виртуальным параметрам, которые не сопоставлены с реальными реквизитами базы, должен выполняться только программно. Для реализации нестандартного сопоставления объектов также может пригодиться пример настройки поиска при загрузке по дополнительному реквизиту.

Важный нюанс: коллекция «ПараметрыОбъекта» и флаг «Поиск»

Это один из самых коварных «подводных камней» КД 2.1. В обработчике «Поля поиска» коллекция ПараметрыОбъекта по умолчанию содержит только те параметры, для которых в настройках правил конвертации свойств (ПКС) установлен флаг «Поиск».

Если вы передали параметр из базы-источника, но забыли поставить напротив него галочку «Поиск» в таблице ПКС вашего ПКО, то в данном событии при попытке обратиться к коллекции вы получите Неопределено или вызовете ошибку отсутствия ключа в соответствии. Всегда проверяйте коллекцию на заполненность перед получением значений! Для более удобной работы с переменными обработчиков событий и навигации по правилам можно использовать доработанную конфигурацию «Конвертация данных 2.1» с контекстными подсказками.

Пошаговый алгоритм реализации поиска по параметру

Рассмотрим пошагово, как настроить надежный поиск номенклатуры по артикулу, наименованию и, в крайнем случае, по очищенному от префикса коду из параметра.

Шаг 1. Настройка ПКО и передача параметра

В настройках ПКО для справочника Номенклатура перейдите на вкладку «Параметры» и добавьте параметр Пар_Код. В правилах конвертации свойств (ПКС) настройте передачу значения Источник.Код в этот параметр. Обязательно установите флаг «Поиск» для этого параметра в таблице ПКС! При этом сам реквизит Код передавать в приемник напрямую не нужно, чтобы не нарушать автонумерацию при создании новых позиций.

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

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

  1. Поиск по связке «Артикул + Наименование».
  2. Поиск по «Наименованию» (если артикул не заполнен).
  3. Программный поиск по параметру Пар_Код с предварительным удалением префикса источника.
  4. Если ничего не найдено, прекращаем поиск и разрешаем создание нового объекта с автономером приемника.

Посмотрим на пример реализации этого алгоритма:


// Шаг 1: Ищем по наиболее точному совпадению (Артикул + Наименование)
Если НомерВариантаПоиска = 1 Тогда
    
    СтрокаИменСвойствПоиска = "Артикул, Наименование";

// Шаг 2: Если первый шаг не дал результатов, пробуем искать только по Наименованию
ИначеЕсли НомерВариантаПоиска = 2 Тогда
    
    СтрокаИменСвойствПоиска = "Наименование";

// Шаг 3: Программный поиск по переданному коду источника (с очисткой от префикса)
ИначеЕсли НомерВариантаПоиска = 3 Тогда
    
    // Обязательно проверяем доступность коллекции параметров
    Если ПараметрыОбъекта <> Неопределено Тогда
        
        ИсходныйКод = ПараметрыОбъекта.Получить("Пар_Код");
        
        Если ЗначениеЗаполнено(ИсходныйКод) Тогда
            
            // Предположим, префикс источника имеет вид "ПРФ-" (длина 4 символа)
            // Выполним очистку кода перед поиском в базе-приемнике
            ОчищенныйКод = ИсходныйКод;
            Если Найти(ОчищенныйКод, "-") > 0 Тогда
                // Отсекаем префикс и дефис, оставляя только числовую часть
                ПозицияДефиса = Найти(ОчищенныйКод, "-");
                ОчищенныйКод = Сред(ОчищенныйКод, ПозицияДефиса + 1);
            КонецЕсли;
            
            // Выполняем непосредственный поиск в базе приемника
            НайденнаяСсылка = Справочники.Номенклатура.НайтиПоКоду(ОчищенныйКод);
            
            Если Не НайденнаяСсылка.Пустая() Тогда
                // Объект найден! Записываем его в предопределенную переменную СсылкаНаОбъект
                СсылкаНаОбъект = НайденнаяСсылка;
                // Прекращаем дальнейшие итерации поиска
                ПрекратитьПоиск = Истина;
            КонецЕсли;
            
        КонецЕсли;
        
    КонецЕсли;
    
// Шаг 4: Если все варианты исчерпаны, и объект не найден
Иначе
    
    // Предотвращаем бесконечный цикл поиска и даем КД команду создать новый элемент
    ПрекратитьПоиск = Истина;
    
КонецЕсли;

Разбор логики работы флага «ПрекратитьПоиск»

Проанализируем, почему критически важно правильно позиционировать флаг ПрекратитьПоиск. В ветке обсуждения на форуме один из участников предлагал установить этот флаг в самом конце обработчика вне конструкции Если...КонецЕсли.

Делать так категорически нельзя. Если вы установите ПрекратитьПоиск = Истина глобально для всего обработчика, система выполнит только первый шаг поиска (НомерВариантаПоиска = 1). Если по связке «Артикул + Наименование» ничего не будет найдено, КД сразу же прекратит дальнейшие попытки поиска и перейдет к созданию нового объекта. До шагов с поиском по наименованию и коду алгоритм просто не дойдет.

Запомните правило:

← На главную