Разберем ситуацию, с которой часто сталкиваются программисты 1С при интеграции и динамическом разборе XML-файлов. Иногда, в том числе в типовых конфигурациях (например, 1С:Зарплата и Управление Персоналом или модулях БСП), можно встретить участки кода, где разработчики пытаются проверить ОбъектXDTO на пустоту с помощью стандартной функции ЗначениеЗаполнено(). Однако при выполнении такого кода платформа 1С прерывает работу с системной ошибкой. Проанализируем причину такого поведения, выясним, почему встроенный механизм дает сбой, и посмотрим на правильные варианты решения этой задачи.
Давайте подробно рассмотрим механику работы встроенной функции. Функция ЗначениеЗаполнено() в платформе 1С умеет определять «пустоту» только для строго определенных типов данных. К ним относятся:
В свою очередь, ОбъектXDTO является сложной, специфической системной оберткой над узлами и данными XML. Платформа 1С на базовом уровне не имеет универсального встроенного критерия того, что именно считать «пустым» объектом XDTO. Поэтому, когда мы передаем сам объект целиком в эту функцию, платформа не знает, как его интерпретировать, и логично генерирует ошибку.
Проанализируем ситуацию с чтением XML. Ошибка часто проявляется при работе с методом ФабрикаXDTO.ПрочитатьXML(). Проблема заключается в том, как фабрика обрабатывает пустые теги в файле, если они жестко не описаны в XSD-схеме.
Представим, что в исходном XML есть пустой тег (например, одиночный тег без содержимого). При чтении такого узла программист обычно ожидает получить базовое пустое значение: либо Неопределено, либо пустую строку. Однако фабрика XDTO может создать и вернуть именно пустой ОбъектXDTO. Разработчик, не подозревая подвоха, применяет стандартную проверку на заполненность, и программа завершается с ошибкой.
Важно отметить: наличие кода вида ЗначениеЗаполнено(ОбъектXDTO) в типовых конфигурациях — это недоработки самих разработчиков фирмы 1С. Такие участки обычно исправляются в новых релизах и патчах, где ошибочные функции заменяются на безопасные проверки.
Разберем по шагам, как нужно писать код, чтобы избежать падений программы при работе с фабрикой XDTO. У нас есть несколько надежных вариантов.
1. Проверка объекта на равенство Неопределено
Если нам нужно проверить сам факт того, инициализирован ли объект и получены ли данные из XML-узла, вместо проверки на заполненность необходимо использовать оператор сравнения с типом Неопределено.
Если ОбъектXDTO <> Неопределено Тогда
// Объект существует, можно работать с его свойствами
Сообщить("Данные успешно прочитаны");
КонецЕсли;
2. Применение функции к свойствам объекта
Хотя сам ОбъектXDTO проверять нельзя, функцию ЗначениеЗаполнено() можно и нужно применять к конкретным свойствам (полям) этого объекта. Если вы обращаетесь к свойству, которое содержит примитивный тип данных (число или строку), проверка отработает абсолютно корректно.
Если ОбъектXDTO <> Неопределено Тогда
// Проверяем конкретное свойство внутри XDTO-объекта
Если ЗначениеЗаполнено(ОбъектXDTO.ИНН) Тогда
ИНН_Контрагента = ОбъектXDTO.ИНН;
Иначе
Сообщить("Узел ИНН пуст!");
КонецЕсли;
КонецЕсли;
3. Комбинированная безопасная проверка
Если мы пишем универсальный алгоритм (например, динамический обход дерева XML), и в переменной может оказаться как примитивное значение, так и вложенный ОбъектXDTO, безопасная проверка должна состоять из нескольких этапов. Сначала мы отсекаем Неопределено, затем проверяем тип значения, и только убедившись, что перед нами не XDTO-объект, используем стандартную функцию.
Посмотрим на пример такой универсальной проверки:
Если ПеременнаяXML <> Неопределено Тогда
// Отсекаем сам ОбъектXDTO, чтобы не вызвать ошибку
Если ТипЗнч(ПеременнаяXML) <> Тип("ОбъектXDTO") Тогда
// Теперь безопасно проверяем примитивные типы
Если ЗначениеЗаполнено(ПеременнаяXML) Тогда
Результат = ПеременнаяXML;
КонецЕсли;
Иначе
// Логика обработки вложенного сложного узла XDTO
ОбработатьВложенныйУзел(ПеременнаяXML);
КонецЕсли;
КонецЕсли;
Подводя итоги, запомним главное правило: никогда не передавайте сам ОбъектXDTO в функцию ЗначениеЗаполнено(). Всегда проверяйте его на Неопределено, а функцию применяйте исключительно к его типизированным свойствам. Применяя этот подход, вы навсегда избавитесь от неожиданных сбоев при разборе XML-сообщений в 1С.