«Значение не является значением объектного типа» в 1С: причины и решение
Код обращается к свойству или методу через точку, но в переменной лежит не объект, а Неопределено, NULL, число, строка или другое примитивное значение. В скобках платформа указывает имя свойства, на котором произошёл сбой.
Текст ошибки
Причины
- Функция поиска вернула Неопределено, а код сразу обращается к результату через точку
- Реквизит или параметр не заполнен, и в нём пусто
- В поле составного типа оказалось значение другого типа
- В запросе поле получило NULL после левого соединения
- Пользовательские данные в базе отличаются от ожидаемых: удалённый объект, «битая» ссылка
Как найти место ошибки
В тексте сообщения есть модуль и номер строки, например {ОбщийМодуль.Продажи.Модуль(125)}. Откройте эту строку в конфигураторе: слева от имени в скобках стоит выражение, значение которого оказалось не объектом. Если ошибка воспроизводится, поставьте точку останова и посмотрите значение переменной в отладчике (Shift+F9).
Для пользователя
- Проверьте, заполнены ли в документе или справочнике все обязательные поля, особенно те, что связаны с операцией: склад, организация, договор, номенклатура.
- Если ошибка появляется на конкретном документе, откройте связанные с ним объекты: часто ссылка указывает на удалённый элемент (в поле видно «<Объект не найден>»). Выберите корректное значение заново.
- Если ошибка возникает в типовой конфигурации без доработок, обновите её до актуального релиза: такие сбои часто исправляются в обновлениях.
Для разработчика: проверки перед обращением
Методы Найти() у таблицы значений и коллекций, Получить() у соответствия, обращение к строке по индексу могут вернуть Неопределено. Методы менеджеров НайтиПоКоду() и НайтиПоНаименованию() возвращают пустую ссылку, а обращение к реквизитам пустой ссылки тоже даёт пустые значения, которые дальше по цепочке ломают код.
Строка = ТаблицаТоваров.Найти(Номенклатура, "Номенклатура");
Если Строка = Неопределено Тогда
Возврат;
КонецЕсли;
Количество = Строка.Количество;
Если Не ЗначениеЗаполнено(Документ.Склад) Тогда
ВызватьИсключение "Не заполнен склад";
КонецЕсли;
// Для составного типа проверяем тип значения
Если ТипЗнч(Значение) = Тип("СправочникСсылка.Номенклатура") Тогда
ЕдиницаИзмерения = Значение.ЕдиницаИзмерения;
КонецЕсли;
NULL в результате запроса
При левом соединении поля правой таблицы приходят как NULL, если пары не нашлось. Заменяйте их в самом запросе через ЕСТЬNULL(), тогда в коде не придётся проверять каждое значение.
ВЫБРАТЬ
Товары.Номенклатура,
ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток
ИЗ
Документ.РеализацияТоваров.Товары КАК Товары
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
ПО Товары.Номенклатура = Остатки.Номенклатура
Структуры и параметры
Если значение приходит из структуры параметров, проверяйте наличие ключа методом Свойство(). На клиенте управляемой формы держите под рукой только те данные, которые реально переданы с сервера: реквизиты ссылок удобнее получать серверной функцией и возвращать на клиент готовым значением.
Частые вопросы
Чем эта ошибка отличается от «Поле объекта не обнаружено»?
Здесь в переменной вообще не объект (например, Неопределено), поэтому у неё нет никаких свойств. «Поле объекта не обнаружено» означает, что объект есть, но свойства с таким именем у него нет.
Ошибка появилась после обновления типовой конфигурации. Что делать?
Проверьте, не мешают ли доработки и расширения: отключите расширения и повторите операцию. Если без них ошибки нет, исправляйте расширение под новый релиз.