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