При доработке типовых обменов по технологии Конвертация данных 3.0 (КД 3) на базе формата EnterpriseData разработчики часто сталкиваются с ситуацией, когда добавленный в расширение XDTO-пакета реквизит с типом Дата (например, ДатаНачалаДействия) на стороне базы-приемника считывается в объект ДанныеXDTO как обычная строка. В результате стандартные механизмы БСП не могут корректно сопоставить и записать это свойство в базу данных.
В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем внутреннее устройство фабрики XDTO 1С, рассмотрим два способа решения проблемы (быстрый через обработчики и правильный через настройку схем), а также научимся перехватывать и анализировать файл XML-выгрузки.
Для того чтобы понять суть проблемы, нам нужно заглянуть под капот механизма сериализации XDTO в платформе 1С:Предприятие. Когда база-приемник читает XML-файл сообщения обмена, она выполняет следующий код в общем модуле ОбменДаннымиXDTOСервер:
ТипОбъектаXDTO = ФабрикаXDTO.Тип(КомпонентыОбмена.ФайлОбмена.URIПространстваИмен, КомпонентыОбмена.ФайлОбмена.ЛокальноеИмя);
ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(КомпонентыОбмена.ФайлОбмена, ТипОбъектаXDTO);
Типовые реквизиты конфигурации описаны в основном XDTO-пакете (например, EnterpriseData_1_16_2). Платформа заранее инициализирует фабрику XDTO с использованием этих статических схем. В схеме для каждого стандартного реквизита даты жестко указан тип xs:date или xs:dateTime. Фабрика XDTO, видя эти типы в схеме, автоматически преобразует строковое представление даты из XML (например, "2023-10-25") в стандартный тип 1С Дата.
Если же мы расширяем формат и добавляем новое свойство, ситуация меняется. Автоматическое приведение типов может дать сбой по одной из следующих причин:
string вместо date (http://www.w3.org/2001/XMLSchema).Если вам необходимо быстро решить задачу и вы не хотите тратить время на повторную перегенерацию схем, регистрацию пространств имен и перезагрузку правил в КД 3, вы можете обработать значение свойства вручную на стороне приемника.
Для этого используется обработчик ПриКонвертацииДанныхXDTO в правилах конвертации объектов (ПКО). Давайте разберем по шагам, как настроить этот процесс.
Шаг 1. В модуле менеджера обмена базы-приемника найдите процедуру, отвечающую за получение данных вашего объекта (например, ДобавитьПКО_Справочник_ДоговорыКонтрагентов_Получение).
Шаг 2. Убедитесь, что ваше расширенное свойство добавлено в состав ПКС (Правила конвертации свойств). Обратите внимание на четвертый параметр функции ДобавитьПКС. Если мы хотим обрабатывать свойство алгоритмами, здесь должна быть передана единица (или Истина в зависимости от версии БСП), указывающая на получение значения алгоритмом:
ПространствоИмен = "";
ОбменДаннымиXDTOСервер.ИнициализироватьРасширениеПравилаКонвертацииОбъекта(ПравилоКонвертации, ПространствоИмен);
// Четвертый параметр = 1 указывает на использование алгоритмов при конвертации
ДобавитьПКС(СвойстваШапки, "ДатаНачалаДействия", "ДатаНачалаДействия", 1, , ПространствоИмен);
Шаг 3. Перейдем к обработчику события. В модуле менеджера обмена (или в соответствующем обработчике ПКО в КД 3) необходимо прописать код преобразования полученной строки в полноценную дату 1С. Для этого используется системная функция XMLЗначение():
Процедура ПКО_Справочник_ДоговорыКонтрагентов_Получение_ПриКонвертацииДанныхXDTO(ДанныеXDTO, ДанныеПовторногоИспользования, ПолученныеДанные, КомпонентыОбмена)
// Проверяем наличие нашего свойства в XDTO
Если ДанныеXDTO.Свойство("ДатаНачалаДействия") И ЗначениеЗаполнено(ДанныеXDTO.ДатаНачалаДействия) Тогда
ЗначениеРеквизита = ДанныеXDTO.ДатаНачалаДействия;
// Если значение пришло в виде строки, принудительно конвертируем его в Дату
Если ТипЗнч(ЗначениеРеквизита) = Тип("Строка") Тогда
Попытка
ПолученныеДанные.ДатаНачалаДействия = XMLЗначение(Тип("Дата"), ЗначениеРеквизита);
Исключение
ЗаписьЖурналаРегистрации("ОбменДанными.ОшибкаТипизацииДаты",
УровеньЖурналаРегистрации.Предупреждение, , ,
"Не удалось сконвертировать дату начала действия: " + ЗначениеРеквизита);
КонецПопытки;
Иначе
// Если платформа сама смогла типизировать (например, после обновления схем)
ПолученныеДанные.ДатаНачалаДействия = ЗначениеРеквизита;
EndIf;
КонецЕсли;
КонецПроцедуры
Этот подход гарантирует стабильную работу обмена даже в том случае, если схемы конфигураций источника и приемника временно рассинхронизированы.
Если вы стремитесь к красивому и правильному решению без написания лишнего "костыльного" кода в обработчиках, необходимо заставить платформу саму распознавать тип данных. Для этого выполним следующие действия:
Шаг 1. Проверка типов в XDTO-пакете конфигуратора
Откройте конфигуратор вашей базы (и источника, и приемника). Найдите ваше расширение XDTO-пакета. Откройте свойства вашего реквизита ДатаНачалаДействия. Убедитесь, что в поле Тип выбрано стандартное значение типа даты из пространства XML-схем: date (http://www.w3.org/2001/XMLSchema).
Шаг 2. Регистрация расширения пространства имен
Платформа должна знать, какие расширения формата подключены к обмену. Для этого в обеих базах в общем модуле ОбменДаннымиПереопределяемый найдите процедуру ПриПолученииДоступныхРасширенийФормата и добавьте туда регистрацию вашего пакета:
Процедура ПриПолученииДоступныхРасширенийФормата(МассивРасширений) Экспорт
// Добавляем URI пространства имен вашего расширения формата
МассивРасширений.Добавить("http://www.your-company.ru/Exchange/Extension");
КонецПроцедуры
Шаг 3. Обновление метаданных в КД 3
Выгрузите обновленные XML-схемы из ваших конфигураций и загрузите их в базу "Конвертация данных 3". В справочнике "Версии формата" проверьте настройки вашего добавленного реквизита. Убедитесь, что КД 3 распознает его тип как Дата. Перегенерируйте модули менеджера обмена и загрузите их в базы источника и приемника.
После выполнения этих шагов платформа при чтении XML автоматически преобразует строку в дату, и в процедуру получения объекта данные придут уже в типизированном виде.
Для диагностики типов данных критически важно уметь смотреть "сырые" данные, которые уходят из источника. Рассмотрим два самых простых способа получить XML-файл обмена:
Самый простой способ изучить файл — настроить синхронизацию через локальный каталог.
.zip (например, Message_ИСТОЧНИК_ПРИЕМНИК.zip). Распакуйте его и откройте находящийся внутри XML-файл с помощью любого текстового редактора (Notepad++, VS Code) или интернет-браузера.Если обмен выполняется напрямую через веб-сервис или COM-соединение, файл создается во временной папке операционной системы и сразу удаляется. Поймать его можно с помощью отладки:
ОбменДаннымиXDTOСервер.ЗаписатьСообщениеОбмена()).ПолучитьИмяВременногоФайла()).В XML-файле найдите узел вашего объекта и посмотрите, как именно выглядит выгруженное свойство. Если оно выглядит как <ДатаНачалаДействия>2023-10-25</ДатаНачалаДействия> без указания префиксов пространства имен, а заголовок файла содержит корректное объявление вашего пространства имен расширения, значит, проблема кроется исключительно на стороне приемника (в регистрации расширения или правилах конвертации).
Используя предложенные методики, вы всегда сможете оперативно диагностировать и устранять любые проблемы с типизацией данных при интеграции систем на платформе 1С:Предприятие 8.