Почему 1С не может прочитать реквизит у пустого значения и как это исправить
Содержание
Ошибка «Значение не является значением объектного типа
» в 1С означает одно: код обратился через точку к реквизиту или методу, а в переменной оказалось не объект и не ссылка, а Неопределено, NULL, число, строка или дата. В скобках платформа пишет имя поля, к которому пыталась обратиться, а перед текстом — модуль и номер строки. С этих двух подсказок и начинается исправление.
Частое заблуждение — что база «сломалась» и нужно срочно запускать тестирование и исправление. Обычно с данными всё в порядке. Ошибка программная: где-то не проверили, заполнено ли значение, прежде чем читать его свойство. Пользователь иногда может обойти её, заполнив пустое поле, но окончательно её устраняет правка кода.
Что сообщает текст ошибки и как его прочитать
Полное сообщение выглядит примерно так:
{Документ.РеализацияТоваровУслуг.МодульОбъекта(214)}: Значение не является значением объектного типа (Контрагент)
Разберём по частям:
- 📍
Документ.РеализацияТоваровУслуг.МодульОбъекта— модуль, в котором упал код. Это может быть общий модуль, модуль формы, модуль менеджера, внешняя обработка или расширение. - 🔢
(214)— номер строки в этом модуле. - 🏷️
(Контрагент)в конце — имя свойства, которое код пытался прочитать.
Пример строки, которая даёт такое сообщение: ИНН = Сделка.Контрагент.ИНН;. Если в Сделка лежит Неопределено, платформа не может взять у него поле Контрагент и останавливает выполнение.
У ошибки есть «соседи» с похожим текстом. Их легко спутать, а лечатся они по-разному.
| Текст ошибки | Что произошло | Куда смотреть |
|---|---|---|
Значение не является значением объектного типа (Поле) | У переменной нет свойств вообще: в ней Неопределено, NULL или примитив | Откуда пришло значение слева от точки |
Поле объекта не обнаружено (Поле) | Объект есть, но такого реквизита у него нет | Имя реквизита, тип объекта, структура без нужного ключа |
Метод объекта не обнаружен (Метод) | Объект есть, но метода с таким именем у него нет или он недоступен в этом контексте | Имя метода, клиент или сервер |
Откуда в переменной берётся «не объект»: основные причины
Почти все случаи сводятся к семи ситуациям. Их полезно знать, чтобы по строке кода сразу понять, что пошло не так.
- 🕳️ Функция вернула
Неопределено. МетодНайти()у таблицы значений или массива,НайтиСтроки()с пустым результатом, собственная функция безВозвратв одной из веток. Следующая строка читает поле у результата — и падает. - 🧩 Реквизит составного типа не заполнен. Пустой реквизит составного типа хранит
Неопределено, а не пустую ссылку. Код рассчитывает на ссылку и обращается к её полям. - 🔀 В составном реквизите лежит примитив. Реквизит допускает строку и ссылку, пользователь ввёл текст. Обращение
.Наименованиек строке даёт ту же ошибку. - 🗃️
NULLиз запроса. Левое соединение без пары, поле через точку от пустого значения, итоги по группировкам. В выборке приходитNULL, а код читает его реквизиты. - 🖱️ В списке формы не выбрана строка.
Элементы.Список.ТекущиеДанныевозвращаетНеопределено, если курсор не стоит на строке. Нажатие кнопки в пустом списке — классический сценарий. - 📦 Параметр не передали. Процедуру вызвали без нужного параметра, у него значение по умолчанию
Неопределено. Или форму открыли без ключа, который ожидает её код. - 🔄 Код написан под другой релиз. Внешняя печатная форма, обработка или расширение обращаются к реквизиту, который в новой версии типовой конфигурации переименовали или сделали другого типа.
Отдельно про пустые и битые ссылки. Если в переменной пустая ссылка нужного типа или ссылка на удалённый объект («Объект не найден»), чтение реквизита обычно не вызывает эту ошибку: платформа вернёт пустое значение. Поэтому Справочники.Контрагенты.ПустаяСсылка().ИНН отработает без исключения, а Неопределено.ИНН — нет.
Если ошибка возникает не у всех документов, а только у некоторых, ищите разницу в данных: у «плохих» документов почти всегда пусто какое-то поле составного типа или выбрано значение другого типа.
Как найти место, где возникает ошибка
Сначала нужен точный текст. Без него программист будет гадать.
Что может сделать пользователь
- В окне ошибки нажмите ссылку
ПодробноилиПодробный текст ошибки. Откроется полный текст с модулем, строкой и стеком вызовов. - Скопируйте текст целиком, вместе с фигурными скобками. Сделайте снимок экрана документа, на котором всё произошло.
- Запишите, какую кнопку нажимали: «Провести», «Печать», «Заполнить», открытие формы. Одна и та же ошибка при печати и при проведении — это разные места в коде.
- Если окно закрыли, найдите запись в журнале регистрации:
Администрирование → Обслуживание → Журнал регистрации. Отберите события с уровнем «Ошибка» за нужное время и пользователя — в комментарии будет тот же текст.
Что делает программист
- Открыть Конфигуратор
и найти модуль из сообщения. Строку удобно открыть через
Ctrl+G(переход к строке по номеру). - Если модуль внешний (обработка, печатная форма) — открыть файл
.epfили.erfв Конфигураторе через менюФайл → Открыть. - Включить остановку по ошибке: в Конфигураторе
Отладка → Остановка по ошибке, затем запустить отладку и повторить действие. Отладчик встанет ровно на проблемной строке. - Посмотреть в табло или в окне вычисления выражения значение переменной слева от точки и её тип через
ТипЗнч().
Отладку в рабочей базе под нагрузкой не запускайте: остановка на точке держит сеанс и блокировки, коллеги могут ждать. Повторите сценарий на копии базы, если ошибка воспроизводится там.
Когда известна строка и тип значения, причина становится очевидной. Остаётся выбрать способ исправления.
Элементы.Список.ТекущиеДанные, а строка не выбрана. Пользователю: выделите строку и повторите. Программисту: добавьте проверку Если ТекущиеДанные = Неопределено Тогда Возврат; КонецЕсли;.ТипЗнч().NULL из левого соединения или поля через точку. Оберните поле в запросе в ЕСТЬNULL или проверяйте значение на NULL перед обращением к реквизитам.Пять способов устранить ошибку «не является значением объектного типа»
Способы расположены от безопасных, которые доступны пользователю, к правке кода.
Способ 1. Заполнить пустое поле или выбрать значение нужного типа
Если ошибка возникает на одном документе, откройте его и пройдите по реквизитам, особенно по тем, где можно выбрать значения разных типов (контрагент или физлицо, договор, объект расчётов). Заполните пустое поле. Если там введена строка вместо элемента справочника — выберите элемент из списка. Затем повторите проведение или печать.
Это обходной путь. Код по-прежнему уязвим, но работа не стоит.
Способ 2. Отключить внешнюю обработку или расширение
Если сбой начался после обновления, в первую очередь подозревайте доработки. В типовых конфигурациях на БСП они собраны в Администрирование → Печатные формы, отчеты и обработки: там есть списки дополнительных отчётов и обработок и расширений.
- Откройте список расширений и снимите флажок активности у подозрительного расширения.
- Перезапустите 1С — изменения в расширениях применяются после перезапуска сеанса.
- Повторите действие. Если ошибка ушла, расширение нужно обновить под текущий релиз.
Для внешней печатной формы достаточно временно перевести её в состояние «Отключена» в карточке дополнительной обработки и печатать типовой формой.
Способ 3. Очистить кеш клиента после обновления
Если в тексте ошибки модуль, которого в текущей версии уже нет или строка не совпадает с кодом, клиент мог взять устаревшие данные. Запустите 1С с параметром /ClearCache в ярлыке или в дополнительных параметрах базы в окне запуска. Если не помогло — проблема не в кеше, переходите к коду.
Способ 4. Добавить проверку значения в коде
Это основное исправление. Перед обращением к реквизиту убедитесь, что значение есть и что оно нужного типа. Шаблоны — в следующем разделе.
Способ 5. Исправить запрос, который возвращает NULL
Если значение приходит из запроса, правильнее убрать NULL на уровне запроса, чем ставить проверки на каждой строке выборки.
| Способ | Когда подходит | Кто делает | Риск |
|---|---|---|---|
| Заполнить поле | Ошибка на отдельных документах | Пользователь | Нет, но ошибка вернётся на новом документе |
| Отключить доработку | Сбой после обновления | Администратор | Пропадёт функция расширения до его обновления |
| Очистить кеш | Устаревший модуль в тексте ошибки | Пользователь | Нет |
| Проверка в коде | Любой повторяющийся случай | Программист | Минимальный, если не прятать ошибку |
| Исправить запрос | NULL из соединений и полей через точку | Программист | Изменение логики отчёта, нужна проверка итогов |
Как исправить код: проверки, которые снимают ошибку
Выбор проверки зависит от того, что может прийти в переменную.
Значение может быть Неопределено
Самая частая ситуация — результат поиска или текущие данные формы:
ТекущиеДанные = Элементы.Список.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
Контрагент = ТекущиеДанные.Контрагент;
Для результата Найти():
Строка = ТаблицаТоваров.Найти(Номенклатура, "Номенклатура");
Если Строка <> Неопределено Тогда
Строка.Количество = Строка.Количество + 1;
КонецЕсли;
Значение может быть пустым или NULL
Функция ЗначениеЗаполнено() возвращает Ложь и для Неопределено, и для NULL, и для пустой ссылки. Это удобная универсальная проверка:
Если ЗначениеЗаполнено(Документ.Договор) Тогда
ВалютаДоговора = Документ.Договор.ВалютаВзаиморасчетов;
КонецЕсли;
В составном реквизите может лежать другой тип
Здесь нужна проверка типа, а не заполненности: строка «ООО Ромашка» заполнена, но реквизитов у неё нет.
Если ТипЗнч(Документ.Контрагент) = Тип("СправочникСсылка.Контрагенты") Тогда
ИНН = Документ.Контрагент.ИНН;
Иначе
ИНН = "";
КонецЕсли;
NULL приходит из запроса
Оберните поле в ЕСТЬNULL, чтобы выборка возвращала пустое значение нужного типа:
ВЫБРАТЬ
Реализация.Ссылка КАК Документ,
ЕСТЬNULL(Реализация.Договор.Наименование, "") КАК Договор
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
В типовых конфигурациях на БСП для чтения реквизитов по ссылке есть функция ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "ИмяРеквизита"). Она читает значение запросом и не тянет весь объект в память — это полезно и для скорости.
Почему не стоит прятать ошибку в Попытка…Исключение
Обернуть строку в Попытка … Исключение … КонецПопытки и ничего не делать в блоке исключения — самый быстрый и самый вредный вариант. Ошибка исчезает с экрана, а документ проводится без контрагента или печатается с пустыми полями. Если без перехвата не обойтись, хотя бы запишите событие в журнал регистрации через ЗаписьЖурналаРегистрации() и сообщите пользователю, что поле не заполнено.
Правку кода типовой конфигурации делайте в расширении, а не в основной конфигурации. Иначе конфигурация снимется с полной поддержки, и каждое следующее обновление придётся объединять вручную.
Где ошибка встречается чаще всего
Сама ошибка от конфигурации не зависит — это поведение платформы. Но есть места, где её ловят регулярно:
- 🖨️ Внешние печатные формы. Написаны под конкретный релиз Бухгалтерии или Управления торговлей. После обновления реквизит документа переименовали или сделали составным — форма падает при печати.
- 🔌 Расширения с доработками проведения. Код расширения читает реквизиты, которых в новом релизе больше нет в прежнем виде.
- 📥 Самописные загрузки из Excel. Поиск элемента по наименованию не нашёл совпадения, вернул
Неопределеноили пустую ссылку, а код дальше обращается к найденному элементу. - 📊 Отчёты на запросах с левыми соединениями. Строки без пары дают
NULL, обработка вывода читает у них реквизиты. - 🧾 Документы со «свободным» контрагентом. Поля, где можно выбрать организацию, контрагента или физлицо, особенно в документах движения денег.
В чистой типовой конфигурации без доработок ошибка встречается редко. Если она появилась там, проверьте, установлен ли последний релиз: исправления таких мест обычно выходят в очередных обновлениях.
Как не допустить ошибку в будущем
Профилактика — это дисциплина в коде и в процессе обновлений.
Для программиста:
- ✅ Каждый результат поиска (
Найти,НайтиПоКоду,НайтиПоНаименованию,ТекущиеДанные) проверяйте до обращения к полям. - ✅ Для реквизитов составного типа сравнивайте тип через
ТипЗнч(), а не только заполненность. - ✅ В запросах оборачивайте в
ЕСТЬNULLполя из левых соединений и поля через точку, которые потом читает код. - ✅ Включите проверку кода: в Конфигураторе
Конфигурация → Проверка конфигурацииловит часть проблем со ссылками на несуществующие реквизиты. АПК или EDT дают более глубокий анализ. - ✅ Пишите в функциях явный
Возвратво всех ветках.
Для администратора:
- 🧪 Перед обновлением рабочей базы прогоните его на копии и проверьте печать, проведение основных документов и внешние обработки.
- 📋 Ведите список расширений и внешних форм с указанием релиза, под который они написаны.
- 🛑 После обновления сразу отключайте доработки, которые выдают ошибки, и передавайте их разработчику с точным текстом.
Частые вопросы
Можно ли исправить ошибку тестированием и исправлением информационной базы?
Почему ошибка появляется у одного пользователя и не появляется у другого?
Ошибка в общем модуле типовой конфигурации — значит, ошибка фирмы 1С?
Чем отличается Неопределено от пустой ссылки?
Неопределено нет ни типа объекта, ни реквизитов, поэтому обращение к полю даёт эту ошибку.Ошибка возникает на клиенте в управляемой форме. Что проверить в первую очередь?
Неопределено в клиентском коде.