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