Почему 1С не может прочитать реквизит у пустого значения и как это исправить

· 10 мин

Содержание

Ошибка «Значение не является значением объектного типа » в 1С означает одно: код обратился через точку к реквизиту или методу, а в переменной оказалось не объект и не ссылка, а Неопределено, NULL, число, строка или дата. В скобках платформа пишет имя поля, к которому пыталась обратиться, а перед текстом — модуль и номер строки. С этих двух подсказок и начинается исправление.

Частое заблуждение — что база «сломалась» и нужно срочно запускать тестирование и исправление. Обычно с данными всё в порядке. Ошибка программная: где-то не проверили, заполнено ли значение, прежде чем читать его свойство. Пользователь иногда может обойти её, заполнив пустое поле, но окончательно её устраняет правка кода.

Что сообщает текст ошибки и как его прочитать

Полное сообщение выглядит примерно так:

{Документ.РеализацияТоваровУслуг.МодульОбъекта(214)}: Значение не является значением объектного типа (Контрагент)

Разберём по частям:

  • 📍 Документ.РеализацияТоваровУслуг.МодульОбъекта — модуль, в котором упал код. Это может быть общий модуль, модуль формы, модуль менеджера, внешняя обработка или расширение.
  • 🔢 (214) — номер строки в этом модуле.
  • 🏷️ (Контрагент) в конце — имя свойства, которое код пытался прочитать.

Пример строки, которая даёт такое сообщение: ИНН = Сделка.Контрагент.ИНН;. Если в Сделка лежит Неопределено, платформа не может взять у него поле Контрагент и останавливает выполнение.

У ошибки есть «соседи» с похожим текстом. Их легко спутать, а лечатся они по-разному.

Текст ошибкиЧто произошлоКуда смотреть
Значение не является значением объектного типа (Поле)У переменной нет свойств вообще: в ней Неопределено, NULL или примитивОткуда пришло значение слева от точки
Поле объекта не обнаружено (Поле)Объект есть, но такого реквизита у него нетИмя реквизита, тип объекта, структура без нужного ключа
Метод объекта не обнаружен (Метод)Объект есть, но метода с таким именем у него нет или он недоступен в этом контекстеИмя метода, клиент или сервер

Откуда в переменной берётся «не объект»: основные причины

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

  1. 🕳️ Функция вернула Неопределено. Метод Найти() у таблицы значений или массива, НайтиСтроки() с пустым результатом, собственная функция без Возврат в одной из веток. Следующая строка читает поле у результата — и падает.
  2. 🧩 Реквизит составного типа не заполнен. Пустой реквизит составного типа хранит Неопределено, а не пустую ссылку. Код рассчитывает на ссылку и обращается к её полям.
  3. 🔀 В составном реквизите лежит примитив. Реквизит допускает строку и ссылку, пользователь ввёл текст. Обращение .Наименование к строке даёт ту же ошибку.
  4. 🗃️ NULL из запроса. Левое соединение без пары, поле через точку от пустого значения, итоги по группировкам. В выборке приходит NULL, а код читает его реквизиты.
  5. 🖱️ В списке формы не выбрана строка. Элементы.Список.ТекущиеДанные возвращает Неопределено, если курсор не стоит на строке. Нажатие кнопки в пустом списке — классический сценарий.
  6. 📦 Параметр не передали. Процедуру вызвали без нужного параметра, у него значение по умолчанию Неопределено. Или форму открыли без ключа, который ожидает её код.
  7. 🔄 Код написан под другой релиз. Внешняя печатная форма, обработка или расширение обращаются к реквизиту, который в новой версии типовой конфигурации переименовали или сделали другого типа.

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

Если ошибка возникает не у всех документов, а только у некоторых, ищите разницу в данных: у «плохих» документов почти всегда пусто какое-то поле составного типа или выбрано значение другого типа.

Как найти место, где возникает ошибка

Сначала нужен точный текст. Без него программист будет гадать.

Что может сделать пользователь

  1. В окне ошибки нажмите ссылку Подробно или Подробный текст ошибки. Откроется полный текст с модулем, строкой и стеком вызовов.
  2. Скопируйте текст целиком, вместе с фигурными скобками. Сделайте снимок экрана документа, на котором всё произошло.
  3. Запишите, какую кнопку нажимали: «Провести», «Печать», «Заполнить», открытие формы. Одна и та же ошибка при печати и при проведении — это разные места в коде.
  4. Если окно закрыли, найдите запись в журнале регистрации: Администрирование → Обслуживание → Журнал регистрации. Отберите события с уровнем «Ошибка» за нужное время и пользователя — в комментарии будет тот же текст.

Что делает программист

  1. Открыть Конфигуратор и найти модуль из сообщения. Строку удобно открыть через Ctrl+G (переход к строке по номеру).
  2. Если модуль внешний (обработка, печатная форма) — открыть файл .epf или .erf в Конфигураторе через меню Файл → Открыть.
  3. Включить остановку по ошибке: в Конфигураторе Отладка → Остановка по ошибке, затем запустить отладку и повторить действие. Отладчик встанет ровно на проблемной строке.
  4. Посмотреть в табло или в окне вычисления выражения значение переменной слева от точки и её тип через ТипЗнч().

Отладку в рабочей базе под нагрузкой не запускайте: остановка на точке держит сеанс и блокировки, коллеги могут ждать. Повторите сценарий на копии базы, если ошибка воспроизводится там.

Когда известна строка и тип значения, причина становится очевидной. Остаётся выбрать способ исправления.

Диагностика: выберите симптом

Пять способов устранить ошибку «не является значением объектного типа»

Способы расположены от безопасных, которые доступны пользователю, к правке кода.

Способ 1. Заполнить пустое поле или выбрать значение нужного типа

Если ошибка возникает на одном документе, откройте его и пройдите по реквизитам, особенно по тем, где можно выбрать значения разных типов (контрагент или физлицо, договор, объект расчётов). Заполните пустое поле. Если там введена строка вместо элемента справочника — выберите элемент из списка. Затем повторите проведение или печать.

Это обходной путь. Код по-прежнему уязвим, но работа не стоит.

Способ 2. Отключить внешнюю обработку или расширение

Если сбой начался после обновления, в первую очередь подозревайте доработки. В типовых конфигурациях на БСП они собраны в Администрирование → Печатные формы, отчеты и обработки: там есть списки дополнительных отчётов и обработок и расширений.

  1. Откройте список расширений и снимите флажок активности у подозрительного расширения.
  2. Перезапустите 1С — изменения в расширениях применяются после перезапуска сеанса.
  3. Повторите действие. Если ошибка ушла, расширение нужно обновить под текущий релиз.

Для внешней печатной формы достаточно временно перевести её в состояние «Отключена» в карточке дополнительной обработки и печатать типовой формой.

Способ 3. Очистить кеш клиента после обновления

Если в тексте ошибки модуль, которого в текущей версии уже нет или строка не совпадает с кодом, клиент мог взять устаревшие данные. Запустите 1С с параметром /ClearCache в ярлыке или в дополнительных параметрах базы в окне запуска. Если не помогло — проблема не в кеше, переходите к коду.

Способ 4. Добавить проверку значения в коде

Это основное исправление. Перед обращением к реквизиту убедитесь, что значение есть и что оно нужного типа. Шаблоны — в следующем разделе.

Способ 5. Исправить запрос, который возвращает NULL

Если значение приходит из запроса, правильнее убрать NULL на уровне запроса, чем ставить проверки на каждой строке выборки.

СпособКогда подходитКто делаетРиск
Заполнить полеОшибка на отдельных документахПользовательНет, но ошибка вернётся на новом документе
Отключить доработкуСбой после обновленияАдминистраторПропадёт функция расширения до его обновления
Очистить кешУстаревший модуль в тексте ошибкиПользовательНет
Проверка в кодеЛюбой повторяющийся случайПрограммистМинимальный, если не прятать ошибку
Исправить запросNULL из соединений и полей через точкуПрограммистИзменение логики отчёта, нужна проверка итогов

Как исправить код: проверки, которые снимают ошибку

Выбор проверки зависит от того, что может прийти в переменную.

Значение может быть Неопределено

Самая частая ситуация — результат поиска или текущие данные формы:

ТекущиеДанные = Элементы.Список.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
	Возврат;
КонецЕсли;
Контрагент = ТекущиеДанные.Контрагент;

Для результата Найти():

Строка = ТаблицаТоваров.Найти(Номенклатура, "Номенклатура");
Если Строка <> Неопределено Тогда
	Строка.Количество = Строка.Количество + 1;
КонецЕсли;

Значение может быть пустым или NULL

Функция ЗначениеЗаполнено() возвращает Ложь и для Неопределено, и для NULL, и для пустой ссылки. Это удобная универсальная проверка:

Если ЗначениеЗаполнено(Документ.Договор) Тогда
	ВалютаДоговора = Документ.Договор.ВалютаВзаиморасчетов;
КонецЕсли;

В составном реквизите может лежать другой тип

Здесь нужна проверка типа, а не заполненности: строка «ООО Ромашка» заполнена, но реквизитов у неё нет.

Если ТипЗнч(Документ.Контрагент) = Тип("СправочникСсылка.Контрагенты") Тогда
	ИНН = Документ.Контрагент.ИНН;
Иначе
	ИНН = "";
КонецЕсли;

NULL приходит из запроса

Оберните поле в ЕСТЬNULL, чтобы выборка возвращала пустое значение нужного типа:

ВЫБРАТЬ
	Реализация.Ссылка КАК Документ,
	ЕСТЬNULL(Реализация.Договор.Наименование, "") КАК Договор
ИЗ
	Документ.РеализацияТоваровУслуг КАК Реализация

В типовых конфигурациях на БСП для чтения реквизитов по ссылке есть функция ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "ИмяРеквизита"). Она читает значение запросом и не тянет весь объект в память — это полезно и для скорости.

Почему не стоит прятать ошибку в Попытка…Исключение

Обернуть строку в Попытка … Исключение … КонецПопытки и ничего не делать в блоке исключения — самый быстрый и самый вредный вариант. Ошибка исчезает с экрана, а документ проводится без контрагента или печатается с пустыми полями. Если без перехвата не обойтись, хотя бы запишите событие в журнал регистрации через ЗаписьЖурналаРегистрации() и сообщите пользователю, что поле не заполнено.

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

Где ошибка встречается чаще всего

Сама ошибка от конфигурации не зависит — это поведение платформы. Но есть места, где её ловят регулярно:

  • 🖨️ Внешние печатные формы. Написаны под конкретный релиз Бухгалтерии или Управления торговлей. После обновления реквизит документа переименовали или сделали составным — форма падает при печати.
  • 🔌 Расширения с доработками проведения. Код расширения читает реквизиты, которых в новом релизе больше нет в прежнем виде.
  • 📥 Самописные загрузки из Excel. Поиск элемента по наименованию не нашёл совпадения, вернул Неопределено или пустую ссылку, а код дальше обращается к найденному элементу.
  • 📊 Отчёты на запросах с левыми соединениями. Строки без пары дают NULL, обработка вывода читает у них реквизиты.
  • 🧾 Документы со «свободным» контрагентом. Поля, где можно выбрать организацию, контрагента или физлицо, особенно в документах движения денег.

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

Как не допустить ошибку в будущем

Профилактика — это дисциплина в коде и в процессе обновлений.

Для программиста:

  • ✅ Каждый результат поиска (Найти, НайтиПоКоду, НайтиПоНаименованию, ТекущиеДанные) проверяйте до обращения к полям.
  • ✅ Для реквизитов составного типа сравнивайте тип через ТипЗнч(), а не только заполненность.
  • ✅ В запросах оборачивайте в ЕСТЬNULL поля из левых соединений и поля через точку, которые потом читает код.
  • ✅ Включите проверку кода: в Конфигураторе Конфигурация → Проверка конфигурации ловит часть проблем со ссылками на несуществующие реквизиты. АПК или EDT дают более глубокий анализ.
  • ✅ Пишите в функциях явный Возврат во всех ветках.

Для администратора:

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

Частые вопросы

Можно ли исправить ошибку тестированием и исправлением информационной базы?
Как правило, нет. Ошибка возникает в коде, а не в структуре данных. Тестирование помогает с битыми ссылками и индексами, но пустое значение в переменной оно не исправит.
Почему ошибка появляется у одного пользователя и не появляется у другого?
Разные данные или разные действия. Например, у одного в списке выбрана строка, у другого нет. Либо у пользователей разные права, и для одного код идёт по другой ветке.
Ошибка в общем модуле типовой конфигурации — значит, ошибка фирмы 1С?
Не обязательно. Общий модуль часто лишь место, где упал вызов, а неправильное значение передал код выше по стеку — расширение или внешняя обработка. Смотрите стек вызовов в подробном тексте ошибки.
Чем отличается Неопределено от пустой ссылки?
Пустая ссылка имеет тип, например «СправочникСсылка.Контрагенты», и у неё можно читать реквизиты: вернутся пустые значения. У Неопределено нет ни типа объекта, ни реквизитов, поэтому обращение к полю даёт эту ошибку.
Ошибка возникает на клиенте в управляемой форме. Что проверить в первую очередь?
Текущие данные таблицы формы и параметры открытия формы. Это два самых частых источника Неопределено в клиентском коде.