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