Как правильно проверить инициализацию объектной переменной в 1С и избежать ошибок

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

В практике разработки на платформе «1С:Предприятие 8» одной из самых частых ошибок является «Значение не является значением объектного типа». Эта ситуация возникает, когда программный код пытается обратиться к свойству или методу переменной, которая на самом деле не содержит ожидаемого объекта (например, она равна Неопределено или NULL). В этой статье мы подробно разберем, как правильно проверять инициализацию переменных, чем отличаются различные типы «пустых» значений и какие методы проверки наиболее эффективны в разных ситуациях.

Анализ причины ошибки: почему простая проверка не всегда работает

Рассмотрим ситуацию, с которой столкнулся автор темы. В коде была сделана попытка проверить реквизит объекта следующим образом:


Если Рез.Абонент = Неопределено Тогда                                               
   Сообщить("Нет переменной");
Иначе
   Сообщить("Количество записей - " + Рез.СчетчикКоэффициент);
КонецЕсли;

Система выдала ошибку на первой же строке. Выясним причину: ошибка «Значение не является значением объектного типа (Абонент)» означает, что сама переменная Рез в данный момент не является объектом (структурой, ссылкой или документом). Если Рез равна Неопределено, то обращение к Рез.Абонент эквивалентно попытке найти дверь в доме, который еще не построен. Чтобы избежать этого, нам необходимо использовать каскадную проверку или специальные функции платформы.

Способ 1. Иерархическая проверка на Неопределено

Первым делом мы должны убедиться, что сам «контейнер» (переменная Рез) существует и инициализирован. В 1С логические выражения вычисляются слева направо. Если первая часть условия ложна, система во многих случаях прекращает дальнейшие вычисления в этой строке, что позволяет нам писать безопасный код.

Проанализируем правильный подход к иерархической проверке:


Если Рез <> Неопределено И Рез.Абонент <> Неопределено Тогда
    // Здесь мы уверены, что Рез — это объект, и у него есть заполненный Абонент
    Сообщить("Данные найдены");
Иначе
    Сообщить("Объект или реквизит не инициализирован");
КонецЕсли;

Важный нюанс: этот метод эффективен, если мы точно знаем, что Рез — это объект, у которого программно или в конфигураторе жестко задано свойство Абонент.

Способ 2. Использование универсальной функции ЗначениеЗаполнено()

Функция ЗначениеЗаполнено() является наиболее предпочтительной для большинства задач. Она проверяет значение на соответствие «пустоте» для конкретного типа данных. Посмотрим, что она вернет для разных случаев:

Рассмотрим пример использования:


// Безопасная проверка заполнения реквизита
Если ЗначениеЗаполнено(Рез) И ЗначениеЗаполнено(Рез.Абонент) Тогда
    Сообщить("Абонент успешно определен");
Иначе
    Сообщить("Данные отсутствуют");
КонецЕсли;

Однако помните о «подводном камне»: если 0 является для вас валидным (значимым) результатом, ЗначениеЗаполнено() может сослужить плохую службу, посчитав его за отсутствие значения.

Способ 3. Проверка свойств для Структур и Соответствий

Если ваша переменная Рез является Структурой, попытка прямого обращения к отсутствующему ключу Абонент вызовет исключение. В этом случае мы должны использовать метод Свойство(). Это самый надежный способ проверить наличие ключа в коллекции, не вызывая аварийного завершения программы.

Разберем пример работы со структурой:


Если ТипЗнч(Рез) = Тип("Структура") Тогда
    Если Рез.Свойство("Абонент") Тогда
        // Ключ существует, теперь проверим само значение
        Если ЗначениеЗаполнено(Рез.Абонент) Тогда
             Сообщить("Абонент: " + Рез.Абонент);
        КонецЕсли;
    КонецЕсли;
КонецЕсли;

Способ 4. Разграничение Неопределено, NULL и Пустой ссылки

Для качественного кода важно понимать разницу между тремя состояниями «пустоты» в 1С. Выясним, когда какой тип появляется:

  1. Неопределено: Переменная только что создана и ей ничего не присвоили. Это состояние «чистого листа».
  2. NULL: Встречается практически только в результатах запросов, когда данные не найдены (например, при ЛЕВОЕ СОЕДИНЕНИЕ). Сравнение Если Переменная = Неопределено вернет Ложь, если в переменной NULL. Проверять нужно функцией ЭтоNULL().
  3. Пустая ссылка: Объект инициализирован, тип определен (например, СправочникСсылка.Контрагенты), но он указывает на «никуда».

Посмотрим на пример комплексной проверки, учитывающей эти особенности:


Если Рез = NULL Тогда
    Сообщить("Запись в базе данных не найдена (результат запроса)");
ИначеЕсли Рез = Неопределено Тогда
    Сообщить("Переменная не инициализирована в коде");
ИначеЕсли Не ЗначениеЗаполнено(Рез) Тогда
    Сообщить("Ссылка является пустой");
КонецЕсли;

Способ 5. Проверка типа через ТипЗнч()

Иногда полезно убедиться, что в переменной находится именно то, что мы ожидаем, прежде чем обращаться к её свойствам. Это защищает от ситуаций, когда функция в случае ошибки возвращает не объект, а, например, код ошибки в виде числа.


Если ТипЗнч(Рез) = Тип("СправочникСсылка.Абоненты") Тогда
    // Теперь мы точно можем обращаться к реквизитам этой ссылки
    Сообщить(Рез.Наименование);
КонецЕсли;

Рекомендации для стабильного кода

Подводя итог, проанализируем лучшие практики написания кода в 1С для проверки инициализации:

Применяя эти правила, вы сделаете свои обработки и отчеты гораздо устойчивее к ошибкам данных и обеспечите корректную работу программы в любых непредвиденных ситуациях.

← На главную