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