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