Как изменить XDTO-пакет в расширении для обмена через универсальный формат (EnterpriseData)?

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

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

Проблема: ограничения заимствования XDTO

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

Если мы просто добавим реквизит в существующий объект пакета или попробуем изменить тип свойства, при запуске предприятия платформа выдаст ошибку. Более того, даже если удастся технически добавить поле, стандартные механизмы сериализации (СериализаторXDTO) могут игнорировать изменения, продолжая использовать оригинальную схему из основной конфигурации.

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

Подход 1: Отключение контроля свойств (для простых изменений)

Если ваша задача сводится к добавлению нового значения в перечисление (например, новая ставка НДС) внутри пакета XDTO, можно обойтись настройкой свойств заимствования.

Разберем действия по шагам:

  1. Добавьте нужный пакет XDTO в расширение.
  2. Найдите внутри пакета нужный тип объекта (или перечисление) и добавьте его в расширение.
  3. Откройте свойства этого объекта в дереве метаданных расширения.
  4. Обратите внимание на настройки «Контролировать значение свойства» (обычно обозначаются желтым значком рядом со свойством).

Чтобы платформа разрешила внесение изменений, необходимо снять контроль с определенных свойств. Для добавления значения в перечисление часто помогает следующая последовательность:

  1. Заимствуем значение типа из основной конфигурации.
  2. В расширении через копирование (F9) создаем новое значение.
  3. В палитре свойств пакета/объекта играем с переключателями контроля (снимаем галочки контроля, оставляя галочки использования).

Однако, как показывает практика, этот метод нестабилен для добавления новых реквизитов в сложные типы (документы, справочники), так как механизм обмена EnterpriseData жестко привязан к версиям схем.

Подход 2: Создание новой версии формата (Рекомендуемый способ)

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

Суть метода заключается в создании копии пакета с измененным пространством имен (Namespace) и регистрации этой новой версии в механизмах обмена.

Шаг 1. Создание модифицированного пакета

Вместо того чтобы мучиться с заимствованием типового пакета, мы создадим его клон в расширении.

  1. Экспортируйте типовой пакет XDTO (например, EnterpriseData_1_8) в файл XML.
  2. Импортируйте этот пакет в расширение как новый пакет XDTO.
  3. Внесите необходимые правки в структуру нового пакета: добавьте нужные свойства, элементы или типы.
  4. Самое важное: Измените свойство URI пространства имен у нового пакета. Например, если оригинал был http://v8.1c.ru/edi/edi_stnd/EnterpriseData/1.8, измените его на http://v8.1c.ru/edi/edi_stnd/EnterpriseData/1.81 (или добавьте свой суффикс).

Шаг 2. Регистрация новой версии в коде

Теперь нужно «научить» систему видеть нашу версию 1.81. Для этого необходимо переопределить несколько методов в общих модулях, отвечающих за обмен. Обычно это модули ОбменДаннымиXDTOСервер, ОбменДаннымиУТ (или аналогичные для вашей конфигурации, например КА или ERP).

Рассмотрим пример переопределения функции, которая сообщает системе, какие версии формата доступны. Используем аннотацию &После или &Вместо (в зависимости от архитектуры модуля, безопаснее использовать &После для коллекций).


// Модуль: ОбменДаннымиУТ (или аналогичный БП/КА)
// Расширяем процедуру заполнения доступных версий
&После("ДоступныеВерсииУниверсальногоФормата")
Процедура Расш_ДоступныеВерсииУниверсальногоФормата(ВерсииФормата)
    // Регистрируем нашу версию 1.81 и указываем менеджер обмена для нее
    // МенеджерОбменаЧерезУниверсальныйФормат - это общий модуль, содержащий правила конвертации (в отличие от универсальной выгрузки данных, работающей без программирования)
    ВерсииФормата.Вставить("1.81", МенеджерОбменаЧерезУниверсальныйФормат);
КонецПроцедуры

Шаг 3. Подмена версии при согласовании обмена

Далее необходимо вмешаться в процесс определения поддерживаемых объектов. Когда узлы обмениваются информацией, они «договариваются» о версии. Нам нужно подменить версию 1.8 на 1.81 для нужных объектов.

В модуле ОбменДаннымиXDTOСервер (или ОбменДаннымиПовтИсп, зависит от конфигурации) находим функцию ПоддерживаемыеОбъектыФорматаКорреспондента (или ЗаполнитьПоддерживаемыеОбъектыXDTO).


// Модуль: ОбменДаннымиXDTOСервер
&Вместо("ПоддерживаемыеОбъектыФорматаКорреспондента")
Функция Расш_ПоддерживаемыеОбъектыФорматаКорреспондента(УзелОбмена, Режим)
    
    // Получаем стандартную таблицу объектов
    ТаблицаОбъекты = ПродолжитьВызов(УзелОбмена, Режим);
    
    // Проходим по таблице и подменяем версию на нашу кастомную
    Для Каждого Строка Из ТаблицаОбъекты Цикл
        // Если объект поддерживает версию 1.8, переключаем его на нашу 1.81
        Если Строка.Версия = "1.8" Тогда
            Строка.Версия = "1.81";
        КонецЕсли;
    КонецЦикла;
    
    Возврат ТаблицаОбъекты;
    
КонецФункции

Также может потребоваться корректировка в процедуре заполнения поддерживаемых объектов, если конфигурация использует структуру настроек:


// Пример для модуля ОбменДаннымиXDTOСервер
&После("ЗаполнитьПоддерживаемыеОбъектыXDTO")
Процедура Расш_ЗаполнитьПоддерживаемыеОбъектыXDTO(КомпонентыОбмена)
    
    // В структуре КомпонентыОбмена может потребоваться явное указание версии
    // Это зависит от конкретного релиза БСП
    Если КомпонентыОбмена.Свойство("ВерсияФорматаОбмена") И КомпонентыОбмена.ВерсияФорматаОбмена = "1.8" Тогда
        КомпонентыОбмена.ВерсияФорматаОбмена = "1.81";
    КонецЕсли;

КонецПроцедуры

Шаг 4. Обновление настроек обмена (Критический момент)

После внесения изменений в код и пакеты XDTO, обмен может продолжать работать по старой версии (1.8). Это происходит потому, что настройки версий кэшируются в регистре сведений НастройкиОбменаДаннымиXDTO (или аналогичном) при создании настройки синхронизации. Для оперативного пересоздания настроек обмена при тестировании можно использовать обработку для быстрого создания узлов планов обмена.

Чтобы изменения вступили в силу, у вас есть два пути:

  1. Создать новую настройку обмена. При создании новой синхронизации система опросит наш расширенный код, увидит версию 1.81 и запишет её в настройки.
  2. Отредактировать регистр вручную. Если пересоздавать обмен нельзя, откройте регистр сведений НастройкиОбменаДаннымиXDTO (через Функции для технического специалиста) и для вашего узла обмена вручную исправьте версию формата с "1.8" на "1.81".

Реализация выгрузки данных

После того как мы заставили систему использовать наш пакет 1.81, необходимо обеспечить заполнение новых полей данными. Это делается в модуле менеджера обмена (обычно МенеджерОбменаЧерезУниверсальныйФормат). Так как модуль очень большой, его лучше также расширять точечно.

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


// Расширение модуля МенеджерОбменаЧерезУниверсальныйФормат
&После("ПКО_Документ_ПриобретениеТоваровУслуг_Отправка_ПриОбработке")
Процедура Расш_ПКО_Документ_ПриобретениеТоваровУслуг_Отправка_ПриОбработке(ДанныеИБ, ДанныеXDTO, КомпонентыОбмена, СтекВыгрузки)
    
    // Предположим, мы добавили реквизит "NewField" в пакете
    // Нам нужно передать значение из документа в объект XDTO
    
    // Важно: Проверяем, что текущая версия формата именно 1.81, 
    // чтобы не сломать обмен со старыми базами
    Если КомпонентыОбмена.ВерсияФорматаОбмена = "1.81" Тогда
        
        // Создаем свойство, если оно предусмотрено схемой, но не заполнено
        // Или просто присваиваем значение, если структура XDTO уже инициализирована
        
        Попытка
             ДанныеXDTO.NewField = ДанныеИБ.МойНовыйРеквизит;
        Исключение
             // Обработка ошибки, если свойство не найдено в пакете
        КонецПопытки;
        
    КонецЕсли;
    
КонецПроцедуры

Также не забывайте про правила конвертации свойств (ПКС), если вы используете декларативное описание правил обмена. В таком случае в процедуру инициализации правил нужно добавить описание нового свойства.


&После("ПКО_Документ_ПриобретениеТоваровУслуг_ЗаполнитьСвойстваШапки")
Процедура Расш_ПКО_Документ_ПриобретениеТоваровУслуг_ЗаполнитьСвойстваШапки(ПравилаОбработки, КомпонентыОбмена)
    
    Если КомпонентыОбмена.ВерсияФорматаОбмена = "1.81" Тогда
        // Добавляем ПКС: (Коллекция, ИмяВПриемнике, ИмяВИсточнике)
        ДобавитьПКС(ПравилаОбработки, "NewField", "МойНовыйРеквизит"); 
    КонецЕсли;

КонецПроцедуры

Резюме

Изменение XDTO-пакетов в расширении возможно, но требует системного подхода. Простого "заимствования" часто недостаточно из-за жесткого контроля типов.

Наиболее рабочий алгоритм:

  1. Копируем пакет XDTO в расширение целиком.
  2. Меняем URI пространства имен (повышаем версию).
  3. Добавляем нужные поля в новый пакет.
  4. Переопределяем методы регистрации версий формата (ДоступныеВерсии..., ПоддерживаемыеОбъекты...), подменяя старую версию на новую.
  5. Обновляем запись в регистре настроек обмена или пересоздаем синхронизацию.
  6. Дописываем логику заполнения новых полей в менеджере обмена. Для контроля корректности переноса и автоматического поиска расхождений после запуска доработанного обмена удобно использовать программу автоматической сверки проводок между базами 1С.
← На главную