Почему возникает ошибка при применении функции ЗначениеЗаполнено() к ОбъектXDTO в 1С и как ее обойти?

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

Разберем ситуацию, с которой часто сталкиваются программисты 1С при интеграции и динамическом разборе XML-файлов. Иногда, в том числе в типовых конфигурациях (например, 1С:Зарплата и Управление Персоналом или модулях БСП), можно встретить участки кода, где разработчики пытаются проверить ОбъектXDTO на пустоту с помощью стандартной функции ЗначениеЗаполнено(). Однако при выполнении такого кода платформа 1С прерывает работу с системной ошибкой. Проанализируем причину такого поведения, выясним, почему встроенный механизм дает сбой, и посмотрим на правильные варианты решения этой задачи.

Суть проблемы: почему 1С выдает ошибку?

Давайте подробно рассмотрим механику работы встроенной функции. Функция ЗначениеЗаполнено() в платформе 1С умеет определять «пустоту» только для строго определенных типов данных. К ним относятся:

  1. Примитивные типы данных (числа, строки, даты, булево).
  2. Ссылки на объекты базы данных (справочники, документы, перечисления).
  3. Некоторые универсальные коллекции значений (массивы, структуры, списки значений, таблицы значений).

В свою очередь, ОбъектXDTO является сложной, специфической системной оберткой над узлами и данными XML. Платформа 1С на базовом уровне не имеет универсального встроенного критерия того, что именно считать «пустым» объектом XDTO. Поэтому, когда мы передаем сам объект целиком в эту функцию, платформа не знает, как его интерпретировать, и логично генерирует ошибку.

Откуда берутся «пустые» объекты XDTO?

Проанализируем ситуацию с чтением XML. Ошибка часто проявляется при работе с методом ФабрикаXDTO.ПрочитатьXML(). Проблема заключается в том, как фабрика обрабатывает пустые теги в файле, если они жестко не описаны в XSD-схеме.

Представим, что в исходном XML есть пустой тег (например, одиночный тег без содержимого). При чтении такого узла программист обычно ожидает получить базовое пустое значение: либо Неопределено, либо пустую строку. Однако фабрика XDTO может создать и вернуть именно пустой ОбъектXDTO. Разработчик, не подозревая подвоха, применяет стандартную проверку на заполненность, и программа завершается с ошибкой.

Важно отметить: наличие кода вида ЗначениеЗаполнено(ОбъектXDTO) в типовых конфигурациях — это недоработки самих разработчиков фирмы 1С. Такие участки обычно исправляются в новых релизах и патчах, где ошибочные функции заменяются на безопасные проверки.

Правильные способы проверки данных XDTO

Разберем по шагам, как нужно писать код, чтобы избежать падений программы при работе с фабрикой 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С.

← На главную