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