Как исправить ошибку «Значение не является значением объектного типа» во внешней печатной форме ОС-6?

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

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

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

Анализ ошибки 1: «Значение не является значением объектного типа (Наименование)»

Рассмотрим исходную ситуацию. В коде внешней печатной формы выполняется обход коллекции объектов строительства:


Для каждого Элм_Массив ИЗ МассивОбъектовСтроительства Цикл
    СтрокаРаздела7_1.Параметры.НаименованиеОС = Элм_Массив.ОбъектСтроительства.Наименование;
    СтрокаРаздела7_1.Параметры.ТехХарактеристики = Элм_Массив.ТехХарактеристики;
    ТабДок.Вывести(СтрокаРаздела7_1);
КонецЦикла;

Если у какого-то Основного Средства (ОС) не задан объект строительства, то свойство Элм_Массив.ОбъектСтроительства будет иметь значение Неопределено или Null. Попытка обратиться к свойству пустого объекта через точку (в данном случае — к свойству Наименование) незамедлительно вызывает аварийное завершение работы программы.

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

Почему простая проверка «Если ЗначениеЗаполнено()» ломает печать?

Пытаясь исправить ситуацию, разработчики часто совершают ошибку, оборачивая весь блок вывода строки макета в условие:


Если ЗначениеЗаполнено(Элм_Массив.ОбъектСтроительства) Тогда         
    СтрокаРаздела7_1.Параметры.НаименованиеОС = Элм_Массив.ОбъектСтроительства.Наименование;
    СтрокаРаздела7_1.Параметры.ТехХарактеристики = Элм_Массив.ТехХарактеристики;
    ТабДок.Вывести(СтрокаРаздела7_1);
КонецЕсли;

Такой подход в корне неверен по двум причинам:

  1. Если у основного средства отсутствует объект строительства, но при этом заполнены технические характеристики (ТехХарактеристики), эта строка вообще не будет выведена в табличный документ, и пользователь потеряет важные данные.
  2. Если коллекция объектов строительства окажется пустой или ни один объект не пройдет проверку, табличный документ ТабДок не получит ни одной выведенной секции. Это нарушит внутреннюю логику Библиотеки стандартных подсистем (БСП) и приведет к возникновению следующей ошибки.

Правильные варианты исправления первой ошибки

Для корректного обхода проблемы нам необходимо проверять заполненность конкретного реквизита, не препятствуя выводу самой строки макета.

Вариант 1. Использование классического условия (Если...Иначе)

Мы проверяем заполненность ссылки на объект строительства. Если она заполнена, то извлекаем наименование. В противном случае передаем в параметр пустую строку:


Для каждого Элм_Массив ИЗ МассивОбъектовСтроительства Цикл
    Если ЗначениеЗаполнено(Элм_Массив.ОбъектСтроительства) Тогда
        СтрокаРаздела7_1.Параметры.НаименованиеОС = Элм_Массив.ОбъектСтроительства.Наименование;
    Иначе
        СтрокаРаздела7_1.Параметры.НаименованиеОС = "";
    КонецЕсли;
    
    СтрокаРаздела7_1.Параметры.ТехХарактеристики = Элм_Массив.ТехХарактеристики;
    ТабДок.Вывести(СтрокаРаздела7_1);
КонецЦикла;

Вариант 2. Использование тернарного оператора «?» (Лаконичный код)

Этот способ позволяет сократить код и сделать его более читаемым с помощью встроенной функции ветвления:


Для каждого Элм_Массив ИЗ МассивОбъектовСтроительства Цикл
    СтрокаРаздела7_1.Параметры.НаименованиеОС = ?(ЗначениеЗаполнено(Элм_Массив.ОбъектСтроительства), Элм_Массив.ОбъектСтроительства.Наименование, "");
    СтрокаРаздела7_1.Параметры.ТехХарактеристики = Элм_Массив.ТехХарактеристики;
    ТабДок.Вывести(СтрокаРаздела7_1);
КонецЦикла;

Анализ ошибки 2: «Значение не является значением объектного типа (НайтиПоЗначению)»

После применения некорректного условия разработчики часто сталкиваются со следующей ошибкой в общем модуле БСП УправлениеПечатью на строке:

Элемент = ОбъектыПечати.НайтиПоЗначению(Ссылка);

Эта ошибка указывает на то, что переменная ОбъектыПечати имеет значение Неопределено вместо ожидаемого типа СписокЗначений. Выделим основные причины этого поведения:

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

Как гарантированно устранить ошибку в «УправлениеПечатью»?

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


Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
    
    // Защита от незаполненного параметра ОбъектыПечати
    Если ОбъектыПечати = Неопределено Тогда
        ОбъектыПечати = Новый СписокЗначений;
    КонецЕсли;
    
    // Далее идет стандартный код формирования печатных форм...
    
КонецПроцедуры

Если вы запускаете печать интерактивно из отладочной формы, обязательно инициализируйте этот список перед вызовом:


ПараметрыПечати = Новый Структура;
ОбъектыПечатиДляПередачи = Новый СписокЗначений;

// Вызов процедуры печати из модуля объекта внешней обработки
ОбъектВПФ = РеквизитФормыВЗначение("Объект");
ОбъектВПФ.Печать(МассивНашихОС, КоллекцияФорм, ОбъектыПечатиДляПередачи, ПараметрыПечати);

Применение этих простых правил и проверок позволит полностью исключить возникновение ошибок объектного типа и обеспечит бесперебойную печать инвентарных карточек ОС-6 даже для тех основных средств, у которых отсутствуют технические сведения или объекты строительства.

← На главную