В процессе разработки и сопровождения систем на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда стандартный XDTO-пакет в типовой конфигурации содержит ошибки или не соответствует актуальным требованиям обмена. Ярким примером является ситуация с форматом EnterpriseData версии 1.6.1, когда в разных релизах «Бухгалтерии предприятия 3.0» содержимое пакета с одним и тем же пространством имен кардинально отличалось. Рассмотрим подробнее, можно ли решить эту задачу с помощью расширений и какие существуют обходные пути.
Для начала проанализируем, почему стандартный подход «добавить в расширение и изменить» не работает для XDTO-пакетов. В отличие от форм, модулей или некоторых других объектов метаданных, механизм расширений для XDTO-пакетов имеет существенное ограничение:
ПространствомИмен (Target Namespace), то даже если вы добавите пакет с таким же URI в расширение, система при обращении к глобальной фабрике XDTO (через свойство ФабрикаXDTO) будет отдавать предпочтение пакету из основной конфигурации.Таким образом, прямого способа «подменить» пакет в дереве объектов метаданных не существует. Однако мы можем решить проблему программно, изменив логику работы системы с типами XDTO. Рассмотрим основные способы реализации этой задачи.
Поскольку глобальная ФабрикаXDTO инициализируется платформой на основании всех доступных пакетов (с приоритетом основной конфигурации), нам необходимо создать свою локальную фабрику, которая будет содержать «правильный» пакет. Разберем этот процесс по шагам.
Во-первых, добавим в расширение новый XDTO-пакет с исправленной структурой. Чтобы избежать конфликтов, дадим ему уникальное имя, например, EnterpriseData_1_6_1_Исправленный. Пространство имен (URI) можно оставить прежним или изменить — это зависит от того, как реализована логика проверки в коде обмена.
Во-вторых, в коде расширения (через аннотацию &Вместо) нам нужно перехватить момент создания или инициализации фабрики для целей обмена. Проанализируем пример кода, который создает локальную фабрику на основе схем:
// Пример создания локальной фабрики XDTO в расширении
&Вместо("ПолучитьФабрикуXDTOДляОбмена")
Функция Расш1_ПолучитьФабрикуXDTOДляОбмена()
// Получаем схему из нашего исправленного пакета в расширении
ИсправленныйПакет = Метаданные.XDTOPackets.EnterpriseData_1_6_1_Исправленный;
// Создаем набор схем XML
НаборСхем = Новый НаборСхемXML;
// Здесь логика выгрузки схемы пакета в XML
// ...
// Формируем новую фабрику на основании набора схем
НоваяФабрика = СоздатьФабрикуXDTO(НаборСхем);
Возврат НоваяФабрика;
КонецФункции
Используя этот метод, мы заставляем подсистему обмена работать не с глобальным контекстом, а с нашей кастомной фабрикой, где структура пакета соответствует нашим требованиям.
Если нам нужно исправить работу с форматом EnterpriseData (Универсальный формат обмена), стоит обратить внимание на программные модули, отвечающие за версию формата. Выясним причину ошибки: часто система ищет пакет по его версии или URI.
Рассмотрим перехват в модуле менеджера обмена. Мы можем изменить список доступных версий или подменить логику определения типа. Посмотрим на пример перехвата функции, которая сопоставляет версию формата и пакет:
&Вместо("ОпределитьВерсиюИПространствоИмен")
Процедура Расш1_ОпределитьВерсиюИПространствоИмен(ВерсияФормата, ПространствоИмен)
// Вызываем оригинальный обработчик
ПродолжитьВызов(ВерсияФормата, ПространствоИмен);
// Если определилась проблемная версия, подменяем данные
Если ВерсияФормата = "1.6.1" Тогда
// Здесь мы можем перенаправить логику на использование
// нашего исправленного пакета из расширения
ПространствоИмен = "http://v8.1c.ru/edi/edi_stnd/EnterpriseData/1.6.1_fixed";
КонецЕсли;
КонецПроцедуры
Такой подход позволяет оставить основную конфигурацию нетронутой и оперативно внедрить исправления даже в те базы, которые давно не обновлялись.
Это один из самых надежных способов для решения проблем совместимости в расширениях. Вместо того чтобы полагаться на объект метаданных XDTO-пакет, мы можем хранить правильную схему в виде макета (двоичные данные или текстовый документ) внутри расширения.
Проанализируем алгоритм работы:
.xsd.Это полностью исключает влияние «сломанного» пакета из основной конфигурации, так как платформа будет строить модель типов на основании вашей внешней схемы.
При работе с расширением XDTO-пакетов помните о следующих моментах:
Пространства имен: Будьте осторожны с использованием одинаковых URI. Если код типовой конфигурации использует методы типа ФабрикаXDTO.Тип("http://uri", "ИмяТипа"), он всегда будет обращаться к объекту из основной конфигурации. Единственный способ изменить это поведение — перехватить сам вызов метода и подставить туда объект из вашей локальной фабрики.
Режим совместимости: Возможности расширений сильно зависят от версии платформы. Начиная с версии 8.3.10, работа с метаданными в расширениях стала стабильнее, но фундаментальное ограничение на уникальность URI пространств имен в рамках глобальной фабрики сохраняется и в более поздних версиях (8.3.24+).
Обновление конфигурации: Если проблема вызвана ошибкой релиза (как в случае с БП 3.0.60), самым правильным долгосрочным решением остается обновление до исправленного релиза. Использование расширений для подмены XDTO-пакетов — это мощный, но сложный в поддержке инструмент «быстрого реагирования».
Выяснив эти особенности, мы можем сделать вывод: подменить XDTO-пакет «одной кнопкой» в расширении нельзя, но программное управление фабриками XDTO и перехват методов сериализации позволяют реализовать любую необходимую логику обмена без изменения основной конфигурации.