При разработке или доработке печатных форм в системе 1С:Предприятие 8.3 программисты часто сталкиваются с ошибкой: «Значение не является значением объектного типа (Номер)». Эта ситуация может поставить в тупик, особенно когда кажется, что причина кроется в необычном формате номера документа (например, наличии букв). В данной статье мы подробно разберем, почему возникает эта ошибка, развенчаем мифы о префиксах и научимся писать отказоустойчивый код для печати.
Рассмотрим природу ошибки. Сообщение «Значение не является значением объектного типа (ИмяРеквизита)» означает, что программа пытается обратиться к реквизиту (в нашем случае Номер) переменной, которая сама по себе не является объектом. В контексте 1С это означает, что в переменной находится не ссылка на документ, а Неопределено, NULL или ПустаяСсылка.
Многие начинающие разработчики ошибочно полагают, что если в номере документа появилась буква «О» или любой другой символ, 1С не может его прочитать. Это заблуждение. Тип данных Номер в документах 1С — это Строка. Строка может содержать любые символы. Проблема кроется глубже: алгоритм просто «теряет» объект по пути к выводу на печать.
Проанализируем фрагмент кода, в котором чаще всего происходит сбой. Обычно это цикл обхода строк табличной части или результата запроса:
Пока ВыборкаСтрок.Следующий() Цикл
Если ТипЗнч(ВыборкаСтрок.Документ) = Тип("ДокументСсылка.РеализацияТоваровУслуг") Тогда
// Ошибка возникает в следующей строке:
НомерДокумента = ПрефиксацияОбъектовКлиентСервер.НомерНаПечать(ВыборкаСтрок.Документ.Номер, Истина, Ложь);
// ...
КонецЕсли;
КонецЦикла;
В этом примере мы видим прямое обращение через точку: ВыборкаСтрок.Документ.Номер. Если в поле Документ окажется пустое значение, система не сможет найти у него свойство Номер и выдаст критическую ошибку. Выясним причину, почему объект может быть пустым.
Проанализируем ситуацию, когда ошибка проявляется только при наличии определенных документов, например, Корректировки реализации. Рассмотрим три основные причины:
Неопределено.ЛЕВОЕ СОЕДИНЕНИЕ, и для какой-то строки не найдено соответствие, в поле документа попадет NULL.РеализацияТоваровУслуг), а в таблицу попал другой документ, переменные могут остаться неинициализированными.Самый простой и эффективный способ избежать падения системы — добавить проверку ЗначениеЗаполнено() перед обращением к свойствам объекта. Перепишем наш цикл в более безопасном виде:
Пока ВыборкаСтрок.Следующий() Цикл
// Проверяем, что документ вообще существует
Если НЕ ЗначениеЗаполнено(ВыборкаСтрок.Документ) Тогда
Продолжить; // Пропускаем пустую строку
КонецЕсли;
// Проверяем тип документа, включая возможные корректировки
Если ТипЗнч(ВыборкаСтрок.Документ) = Тип("ДокументСсылка.РеализацияТоваровУслуг")
ИЛИ ТипЗнч(ВыборкаСтрок.Документ) = Тип("ДокументСсылка.КорректировкаРеализации") Тогда
НомерДокумента = ПрефиксацияОбъектовКлиентСервер.НомерНаПечать(ВыборкаСтрок.Документ.Номер, Истина, Ложь);
// Дальнейшая логика формирования текста
КонецЕсли;
КонецЦикла;
Для еще большей надежности в типовых конфигурациях (БСП) рекомендуется использовать функцию ОбщегоНазначения.ЗначениеРеквизитаОбъекта(). Она позволяет получить значение реквизита даже от битой ссылки или пустого объекта без вызова исключения.
Рассмотрим пример использования:
// Вместо прямого обращения:
// Номер = ВыборкаСтрок.Документ.Номер;
// Используем безопасный метод:
Номер = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ВыборкаСтрок.Документ, "Номер");
Если Номер = Неопределено Тогда
Номер = "б/н";
КонецЕсли;
Если код кажется правильным, но ошибка сохраняется, воспользуемся отладчиком. Рассмотрим алгоритм действий:
Пока ВыборкаСтрок.Следующий().ВыборкаСтрок.Документ. Если там NULL или {"#", ...} (битая ссылка), значит проблема в данных или запросе.Часто выясняется, что в табличной части документа просто существует лишняя пустая строка, которую пользователь не заметил. В этом случае достаточно добавить программный пропуск пустых строк, как показано в Шаге 3.
Поскольку автор исходного вопроса подозревал буквы в номере, напомним правила работы с функцией НомерНаПечать:
ПрефиксацияОбъектовКлиентСервер.НомерНаПечать специально создана для того, чтобы отсекать префиксы организации и информационных баз. Буква «О» в начале номера часто является частью префикса.«Значение не является значением объектного типа».Номер — это строка. Не пытайтесь преобразовывать его к числу явным образом, если в базе разрешена ручная нумерация.Подведем итог: Ошибка «не является значением объектного типа (Номер)» всегда свидетельствует о попытке «достучаться» до данных пустого объекта. Решением является либо очистка данных (удаление пустых строк в документе), либо добавление в код проверки ЗначениеЗаполнено(), либо использование безопасных методов получения реквизитов из Библиотеки Стандартных Подсистем.