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