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