Обмен данными между различными конфигурациями 1С — одна из самых частых и в то же время непредсказуемых задач, с которыми сталкивается разработчик. Особенно остро проблемы заявляют о себе, когда одна из баз регулярно обновляется (например, типовая 1С:Бухгалтерия 3.0), а вторая является глубоко кастомизированной самопиской. В один прекрасный момент отлаженный годами импорт данных спотыкается на строке ТекущийОбъект = ПрочитатьXML(ЧтениеXML);, выбрасывая абстрактное исключение: «Возможно поменялась структура конфигурации».
В этой статье мы подробно разберем, почему возникает эта ошибка, как работает встроенный механизм сериализации 1С, выясним влияние порядка элементов в схеме XML и рассмотрим конкретные шаги для решения проблемы на примере справочника Номенклатура.
---
Когда мы вызываем метод ПрочитатьXML, платформа 1С пытается автоматически сопоставить узлы XML-файла с физическими реквизитами объекта метаданных в базе-приемнике. Этот процесс называется нативной десериализацией. Платформа крайне требовательна к входящему файлу. Если файл не соответствует внутренним правилам структуры метаданных, чтение прерывается аварийно.
Выделим три основные причины, по которым 1С выбрасывает исключение об изменении структуры конфигурации:
<xs:sequence>). Если порядок нарушен, чтение завершится ошибкой.---
Проанализируем структуру XSD-схемы для справочника Номенклатура, которую нам предоставляет платформа 1С. Обратим внимание на объявление последовательности элементов:
<xs:complexType name="CatalogObject.Номенклатура">
<xs:sequence>
<xs:element name="IsFolder" type="xs:boolean"/>
<xs:element name="Ref" type="tns:CatalogRef.Номенклатура"/>
<xs:element name="DeletionMark" type="xs:boolean"/>
<xs:element name="Parent" type="tns:CatalogRef.Номенклатура"/>
<xs:element name="Code" type="xs:string"/>
<xs:element name="Description" type="xs:string"/>
<!-- Далее идут остальные реквизиты справочника -->
</xs:sequence>
</xs:complexType>
Контейнер <xs:sequence> указывает сериализатору, что элементы в файле XML обязаны располагаться в строго зафиксированной последовательности. Если в выгружаемом файле XML узел <Ref> окажется выше, чем узел <IsFolder>, то платформа 1С при чтении файла через метод ПрочитатьXML выдаст ошибку структуры метаданных. Даже если все реквизиты заполнены абсолютно верно, несоблюдение последовательности тегов гарантированно заблокирует загрузку объекта.
---
Рассмотрим ключевую деталь, из-за которой чаще всего ломаются самописные обмены данными. Выясним разницу между тем, как сериализуются пустые значения различных типов данных.
Для простых типов, таких как строка (xs:string), число (xs:numeric) или булево (xs:boolean), допускается передача пустого значения в виде закрытого тега или пустых скобок, если в схеме указан признак необязательности minOccurs="0". Например, незаполненный артикул или комментарий:
<Артикул />
<Комментарий></Комментарий>
Однако для ссылочных типов (таких как справочники или перечисления) ситуация принципиально иная. Ссылка в 1С — это уникальный идентификатор (UUID). Если реквизит является ссылкой (например, КодРаздел7ДекларацииНДС, который ссылается на соответствующий справочник), то платформа ожидает увидеть внутри тега корректное строковое представление UUID.
Если мы передаем этот реквизит пустым тегом:
<КодРаздел7ДекларацииНДС />
Десериализатор 1С пытается сопоставить пустое значение с типом «УникальныйИдентификатор», не может этого сделать и прерывает чтение с ошибкой структуры конфигурации. Платформа считает, что вместо ожидаемой ссылки ей передали неопределенный простой тип.
Чтобы пустой ссылочный реквизит корректно десериализовался платформой, его необходимо передавать в XML одним из двух способов:
minOccurs="0". Если тега вообще нет в файле, десериализатор запишет в этот реквизит пустую ссылку по умолчанию.
<КодРаздел7ДекларацииНДС>00000000-0000-0000-0000-000000000000</КодРаздел7ДекларацииНДС>
Именно эта деталь часто упускается при написании кастомных алгоритмов выгрузки. Если в коде источника пустая ссылка приводится к пустой строке и выгружается как <Тег />, приемник не сможет прочитать этот объект.
---
Если вы столкнулись с ошибкой «Возможно поменялась структура конфигурации» при загрузке элемента номенклатуры или любого другого сложного объекта, рекомендуем выполнить следующие шаги для локализации и устранения проблемы:
Шаг 1. Получение эталонного XML-файла из базы-приемника.
Для того чтобы понять, какую именно структуру XML ожидает увидеть база-приемник, выполните стандартную интерактивную выгрузку объекта непосредственно из нее. Для этого можно воспользоваться обработкой «Регистрация изменений для обмена» или выгрузить объект в XML программно на стороне приемника с помощью встроенного сериализатора:
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\temp\etalon_nomenklatura.xml");
ЗаписатьXML(ЗаписьXML, СсылкаНаНоменклатуру.ПолучитьОбъект());
ЗаписьXML.Закрыть();
Полученный файл покажет точный порядок тегов, состав реквизитов и формат передачи пустых значений, которые база-приемник считает абсолютно валидными.
Шаг 2. Использование Сериализатора XDTO для получения детальной ошибки.
Стандартный метод ПрочитатьXML скрывает подробности ошибки за общими фразами. Чтобы выяснить, на каком конкретно реквизите спотыкается чтение, используйте в коде загрузки СериализаторXDTO. Заверните чтение в попытку и проанализируйте подробное описание ошибки:
Попытка
// ЧтениеXML предварительно должно быть позиционировано на начале элемента
ТекущийОбъект = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Исключение
ЗаписьЖурналаРегистрации("ОбменДанными.ОшибкаДесериализации",
УровеньЖурналаРегистрации.Ошибка,
,
,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение;
КонецПопытки;
В системном описании ошибки СериализаторXDTO предоставит точную информацию, например: «Ошибка преобразования данных XDTO: НачалоСвойства: КодРаздел7ДекларацииНДС... Ожидается тип...». Это позволит вам мгновенно определить проблемное поле без ручного сравнения сотен строк XML-кода.
Шаг 3. Программная валидация XML-файла по схеме XSD.
Если у вас есть выгруженная схема метаданных базы-приемника в формате XSD, вы можете настроить автоматическую проверку структуры входящих файлов перед их чтением в базу. Это позволит отсекать некорректные пакеты еще на этапе чтения потока:
Схема = Новый СхемаXML;
Схема.Добавить(ПутьКСхемеXSD);
ПакетСхем = Новый ПакетСхемXML;
ПакетСхем.Добавить(Схема);
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлуXML);
ЧтениеXML.УстановитьСхему(ПакетСхем);
Попытка
Пока ЧтениеXML.Прочитать() Цикл
// Платформа автоматически проверяет структуру XML по схеме XSD
КонецЦикла;
Исключение
Сообщить("Файл XML не соответствует схеме: " + ОписаниеОшибки());
КонецПопытки;
---
Ручное написание XML-выгрузки под жесткую структуру метаданных конфигурации-приемника — это, как отмечают многие опытные разработчики, «мина замедленного действия». При каждом обновлении типовой конфигурации состав ее реквизитов будет неизбежно меняться, требуя от вас постоянной ручной переделки схем преобразования.
Рассмотрим альтернативные методы обмена, которые лишены этих недостатков:
Номенклатура, правила сопоставления с форматом EnterpriseData останутся прежними, и ваш обмен не сломается при очередном обновлении.xs:sequence в XML) и по умолчанию игнорирует неизвестные свойства при десериализации. Если в приемнике нет какого-то реквизита, переданного в JSON, платформа просто пропустит его без вызова критических ошибок и аварийного завершения сессии обмена.Применение этих подходов существенно повысит отказоустойчивость ваших интеграционных решений и минимизирует время, затрачиваемое на регулярную поддержку обменов после плановых обновлений программных продуктов 1С.