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