Как привести сильно кастомизированный обмен EnterpriseData к типовому виду и сделать его обновляемым?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При долгой эксплуатации крупных корпоративных систем на базе 1С (таких как 1С:Управление холдингом, 1С:Бухгалтерия предприятия и 1С:Зарплата и управление персоналом) разработчики часто сталкиваются с ситуацией, когда типовой обмен данными на базе формата EnterpriseData превращается в абсолютно неуправляемый монолит. Сотни изменений «внутри» процедур менеджера обмена, измененные напрямую XDTO-пакеты и отсутствие документации превращают каждое обновление конфигурации в персональный кошмар для отдела сопровождения.

В этой статье мы подробно разберем, как полностью спроектировать архитектуру обмена заново, отказаться от практики модификации типового кода, перенести все доработки «вбок» (в расширения конфигурации) и сделать систему легко обновляемой. Мы пройдем весь путь: от анализа существующего хаоса до применения современных механизмов БСП (Библиотеки стандартных подсистем).

Шаг 1. Анализ и реверс-инжиниринг методом «Черного ящика»

Когда перед нами лежат 46 000 строк запутанного кода, написанного разными разработчиками за последние 5 лет, пытаться построчно анализировать каждую процедуру — это путь к выгоранию и потере времени. Нам нужно применить метод анализа результатов работы системы.

Для этого мы выполним следующие действия:

  1. Сформируем эталонные файлы выгрузки. Запустим текущую (кастомизированную) версию обмена и выгрузим XML-файлы с данными по ключевым объектам (Документы, Справочники). Эти файлы станут нашим эталоном («As Is» / «Как есть»).
  2. Сопоставим структуру. Наша главная задача — добиться, чтобы новый, чистый обмен выдавал на выходе точно такую же XML-структуру или корректно интерпретировал её на стороне приемника.
  3. Проведем аудит потребностей. Практика показывает, что до 50% исторических доработок обмена со временем теряют актуальность. Необходимо привлечь бизнес-аналитиков или ключевых пользователей для верификации: действительно ли все эти нетиповые реквизиты до сих пор нужны в принимающей базе.

Шаг 2. Очистка ядра конфигурации и переход на расширения

Чтобы вернуть конфигурацию к полностью обновляемому состоянию, мы должны полностью отказаться от изменений в основной конфигурации. Все правила конвертации объектов (ПКО), правила обработки данных (ПОД) и правила регистрации объектов (ПРО) должны быть вынесены в расширения.

При этом забудьте про директиву #ИзменениеИКонтроль для модулей менеджера обмена. Модули обмена БСП активно развиваются, их структура меняется от релиза к релизу. Вместо этого мы будем использовать событийную модель БСП и перехватывать выполнение процедур с помощью аннотаций &После и &Перед.

Шаг 3. Передача нетиповых данных через AdditionalInfo (Дополнительные данные)

Один из самых изящных способов передать нетиповые реквизиты без изменения структуры XDTO-пакета — это использование стандартного свойства AdditionalInfo. Почти все типы объектов в формате EnterpriseData наследуются от базового типа Object, который уже содержит данное необязательное поле.

Рассмотрим, как программно упаковать кастомные реквизиты на стороне источника и распаковать их на стороне приемника с помощью расширения.

На стороне источника перехватываем процедуру отправки объекта в расширении менеджера обмена:


&После("ПКО_Справочник_Номенклатура_Отправка_ПриОтправкеДанных")
Процедура Расш1_ПКО_Справочник_Номенклатура_Отправка_ПриОтправкеДанных(ДанныеИБ, ДанныеXDTO, КомпонентыОбмена)
    
    // Создаем структуру с нашими нетиповыми реквизитами
    СтруктураДопДанных = Новый Структура;
    СтруктураДопДанных.Вставить("УникальныйИдентификаторИсточника", Строка(ДанныеИБ.Ссылка.УникальныйИдентификатор()));
    СтруктураДопДанных.Вставить("КастомноеСвойствоНоменклатуры", ДанныеИБ.НашКастомныйРеквизит);
    
    // Сериализуем структуру в JSON для передачи в текстовом поле AdditionalInfo
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON(ЗаписьJSON, СтруктураДопДанных);
    СтрокаJSON = ЗаписьJSON.Закрыть();
    
    // Записываем данные в стандартное поле XDTO
    ДанныеXDTO.AdditionalInfo = СтрокаJSON;
    
КонецПроцедуры

На стороне приемника в расширении перехватываем процедуру получения данных, извлекаем информацию из JSON и заполняем реквизиты объекта ИБ:


&После("ПКО_Справочник_Номенклатура_Получение_ПриИмпорте")
Процедура Расш1_ПКО_Справочник_Номенклатура_Получение_ПриИмпорте(ДанныеXDTO, ПолученныеДанные, КомпонентыОбмена)
    
    Если ДанныеXDTO.Свойство("AdditionalInfo") И ЗначениеЗаполнено(ДанныеXDTO.AdditionalInfo) Тогда
        Попытка
            ЧтениеJSON = Новый ЧтениеJSON;
            ЧтениеJSON.УстановитьСтроку(ДанныеXDTO.AdditionalInfo);
            СтруктураДопДанных = ПрочитатьJSON(ЧтениеJSON);
            ЧтениеJSON.Закрыть();
            
            // Заполняем реквизиты в объекте приемника
            Если СтруктураДопДанных.Свойство("КастомноеСвойствоНоменклатуры") Тогда
                ПолученныеДанные.НашКастомныйРеквизитПриемника = СтруктураДопДанных.КастомноеСвойствоНоменклатуры;
            КонецЕсли;
        Исключение
            ЗаписьЖурналаРегистрации("ОбменДанными.ОшибкаРазбораДопДанных",
                УровеньЖурналаРегистрации.Предупреждение, , , 
                ОписаниеОшибки());
        КонецПопытки;
    КонецЕсли;
    
КонецПроцедуры

Этот способ позволяет передавать любые связанные данные, таблицы и структуры без необходимости прикасаться к схеме XSD.

Шаг 4. Расширение формата XDTO (для сложных структур данных)

Если бизнес-логика требует передачи больших табличных частей или новых кастомных справочников/документов, которых нет в стандартной схеме EnterpriseData, механизма AdditionalInfo может не хватить. В этом случае мы воспользуемся возможностями платформы 1С по расширению пакетов XDTO.

Разберем этот процесс по шагам:

  1. В расширении создаем собственный XDTO-пакет со своим уникальным пространством имен (URI), например: http://www.yourcompany.ru/integration/custom.
  2. Импортируем в созданный пакет базовые схемы EnterpriseData нужной вам версии.
  3. Описываем новые свойства или типы объектов в своем XDTO-пакете.
  4. Регистрируем расширение формата в БСП через общий модуль ОбменДаннымиПереопределяемый.

Пример программной регистрации расширения формата XDTO:


&После("ПриПолученииДоступныхРасширенийФормата")
Процедура Расш1_ПриПолученииДоступныхРасширенийФормата(МассивРасширений)
    
    НовоеРасширение = Новый Структура;
    НовоеРасширение.Вставить("ПространствоИмен", "http://www.yourcompany.ru/integration/custom");
    НовоеРасширение.Вставить("Префикс", "cust");
    НовоеРасширение.Вставить("ВерсияФормата", "1.15.1"); // Указываем версию базового ED
    
    МассивРасширений.Добавить(НовоеРасширение);
    
КонецПроцедуры

После регистрации расширения формата платформа автоматически научится валидировать и обрабатывать новые свойства при сериализации и десериализации XML.

Шаг 5. Программное изменение правил конвертации (ПКО и ПОД)

Вместо того чтобы вручную менять таблицы правил обмена в модуле менеджера обмена, мы можем программно модифицировать их в расширении при инициализации правил. Это гарантирует, что при обновлении типовой конфигурации ваши правила не затрутся.

Для добавления или изменения правил используем аннотацию &После для процедур заполнения правил:


&После("ЗаполнитьПравилаКонвертацииОбъектов")
Процедура Расш1_ЗаполнитьПравилаКонвертацииОбъектов(НаправлениеОбмена, ПравилаКонвертации)
    
    // Находим существующее правило для документа Реализация товаров и услуг
    Правило = ПравилаКонвертации.Найти("Документ_РеализацияТоваровУслуг_Отправка", "ИмяПравила");
    Если Правило <> Неопределено Тогда
        // Добавляем новое кастомное свойство в структуру конвертации
        НовоеСвойство = Правило.Свойства.Добавить();
        НовоеСвойство.ИмяСвойстваXDTO = "CustomProperty";
        НовоеСвойство.ИмяСвойстваИБ = "НашКастомныйРеквизит";
    КонецЕсли;
    
КонецПроцедуры

Шаг 6. Настройка правил регистрации объектов «вбок»

Помимо правил конвертации данных, кастомизация часто затрагивает правила регистрации объектов (ПРО) — алгоритмы, определяющие, какие именно документы должны уходить в обмен. Чтобы не править модуль менеджера регистрации, мы можем переопределить логику в расширении.

Для этого в расширении перехватываем процедуру инициализации правил регистрации:


&После("ИнициализацияПравилРегистрации")
Процедура Расш1_ИнициализацияПравилРегистрации(ПравилаРегистрации)
    
    // Переопределяем правила отбора для выгрузки документов
    ПравилоРегистрации = ПравилаРегистрации.Найти("Документ_РеализацияТоваровУслуг", "ИмяОбъекта");
    Если ПравилоРегистрации <> Неопределено Тогда
        // Устанавливаем программный фильтр (например, не регистрировать документы по определенной организации)
        ПравилоРегистрации.СпособВыбораОбъектов = "СОтбором";
        // Программно добавляем условия отбора
    КонецЕсли;
    
КонецПроцедуры

Подведем итоги

Перевод сильно кастомизированного обмена на обновляемые рельсы — задача сложная, но вполне решаемая при системном подходе. Использование событийной модели БСП, передача данных через AdditionalInfo и программная донастройка правил регистрации и конвертации позволяют полностью отказаться от доработок в основной конфигурации.

Благодаря такому подходу вы получите:

← На главную