При настройке обмена данными между конфигурациями 1С часто возникает задача сопоставить объекты не по стандартному внутреннему идентификатору и не по полям поиска (ИНН, Артикул, Наименование), а по конкретному значению ГУИД, которое хранится в базе-источнике как обычная строка или реквизит. В типовом функционале «Конвертации данных 2.1» (КД2) нет прямой галочки «искать по этому реквизиту как по ГУИДу», поэтому нам необходимо использовать программные обработчики. В этой статье мы подробно разберем, как реализовать этот механизм несколькими способами.
Проанализируем самый эффективный метод. Когда система выполняет поиск в приемнике, она оперирует структурой СвойстваПоиска. Если мы передаем наш произвольный ГУИД в ПКС (Правило конвертации свойства), он попадает в эту структуру. Наша задача — перехватить этот момент и сказать системе, что искать нужно именно по внутреннему идентификатору платформы.
Рассмотрим алгоритм действий в обработчике «Поля поиска» на уровне ПКО (Правило конвертации объекта):
GUIDПриемник) в любое свободное поле поиска или просто в ПКС.Пример программного кода:
// Предположим, наше свойство в источнике называется "GUIDПриемник"
// Оно передается в структуру СвойстваПоиска
Если СвойстваПоиска.Свойство("GUIDПриемник") Тогда
// Получаем строковое значение ГУИДа
СтрокаГУИД = СвойстваПоиска.GUIDПриемник;
// Обязательно проверяем на заполненность, чтобы не искать по пустому идентификатору
Если ЗначениеЗаполнено(СтрокаГУИД) Тогда
// Удаляем временное свойство, чтобы оно не мешало стандартному поиску
СвойстваПоиска.Удалить("GUIDПриемник");
// Вставляем значение в специальный ключ "{УникальныйИдентификатор}"
// Ключ ОБЯЗАТЕЛЬНО должен быть в фигурных скобках
СвойстваПоиска.Вставить("{УникальныйИдентификатор}", СтрокаГУИД);
// Если мы хотим найти объект напрямую через менеджер справочника:
Попытка
СсылкаНаОбъект = Справочники[Метаданные.Имя].ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаГУИД));
// Проверяем, существует ли объект в базе
Если СсылкаНаОбъект.ПолучитьОбъект() <> Неопределено Тогда
// Если нашли — прекращаем дальнейшие этапы поиска
ПрекратитьПоиск = Истина;
Иначе
// Если объект не найден, СсылкаНаОбъект все равно будет содержать
// ссылку с нужным ГУИДом. При записи нового объекта 1С назначит ему именно этот ID.
ПрекратитьПоиск = Истина;
КонецЕсли;
Исключение
// Обработка ошибки, если строка ГУИД имеет неверный формат
КонецПопытки;
КонецЕсли;
КонецЕсли;
Разберем ситуацию, когда мы хотим, чтобы объект попал в XML-файл выгрузки уже с «правильным» идентификатором. Это более «чистый» способ с точки зрения файла обмена, так как в узле {UniqueId} сразу будет записано нужное нам значение.
В ПКО в обработчике «Перед выгрузкой» мы можем программно установить идентификатор выгружаемого объекта. Это делается через переменную УзелСвойства или путем манипуляции с источником. Однако наиболее стабильный вариант — передать нужный ГУИД через ПКО_ПередВыгрузкой, установив соответствие.
Выясним причину, почему это удобно: если мы подменим идентификатор при выгрузке, в приемнике сработает стандартный поиск по ГУИД, и нам не придется писать сложный код в «Полях поиска» на стороне приемника.
Проанализируем ситуацию: что делать, если поиск по ГУИД не дал результата и система должна создать новый объект, но именно с тем ГУИДом, который мы передали? Для этого в обработчике «После загрузки» мы можем использовать метод УстановитьСсылкуНового().
Рассмотрим пример кода в обработчике «После загрузки»:
// Проверяем, что объект новый (еще не записан в базу)
Если Объект.ЭтоНовый() Тогда
// Получаем ГУИД из входящих данных (если передавали через ВходящиеДанные)
// Или из реквизита объекта, если он был загружен в текстовое поле
Если ЗначениеЗаполнено(Объект.ВременныйРеквизитГУИД) Тогда
НовыйИдентификатор = Новый УникальныйИдентификатор(Объект.ВременныйРеквизитГУИД);
НужнаяСсылка = Справочники.Контрагенты.ПолучитьСсылку(НовыйИдентификатор);
// Устанавливаем ссылку, которая будет присвоена объекту при записи
Объект.УстановитьСсылкуНового(НужнаяСсылка);
КонецЕсли;
КонецЕсли;
Выделим ключевые моменты, которые часто становятся причиной ошибок при разработке правил обмена:
Новый УникальныйИдентификатор() принимает строго строку определенного формата (например, "550e8400-e29b-41d4-a716-446655440000"). Если передать пустую строку или строку с пробелами, возникнет ошибка выполнения кода. Всегда используйте конструкцию Попытка...Исключение.ПрекратитьПоиск = Истина. В противном случае система продолжит искать объект по остальным полям, отмеченным галочками в ПКС, и может перетереть вашу найденную ссылку.СокрЛП().{УникальныйИдентификатор} является самым быстрым, так как платформа выполняет поиск по первичному ключу таблицы в базе данных SQL.Посмотрим на ситуацию с передачей параметров. Если реквизит ГУИДПриемник не является реальным реквизитом объекта в базе источника, его лучше всего передавать через структуру ИсходящиеДанные в правиле выгрузки данных (ПВД) или ПКО. В приемнике эти данные будут доступны в структуре ВходящиеДанные, что позволит не засорять объект метаданными «мусорными» реквизитами, нужными только для обмена.
Таким образом, мы разобрали, что наиболее гибким инструментом является использование структуры СвойстваПоиска с ключом {УникальныйИдентификатор} в обработчике «Поля поиска». Это позволяет полностью контролировать процесс сопоставления объектов и гарантирует корректную работу системы при любых изменениях в правилах обмена.