Код обратился к полю, которого нет: разбираем сбой «Поле объекта не обнаружено»
Содержание
Сообщение Поле объекта не обнаружено (ИмяПоля) значит одно: код обратился к свойству, которого у этого объекта нет. Платформа не угадывает, что вы имели в виду, а просто останавливает выполнение. Причина почти всегда в одном из трёх: опечатка в имени, объект не того типа, поле пропало после обновления.
Частое заблуждение: «сломалась база, надо чистить кеш и переустанавливать платформу». Нет. Кеш тут ни при чём, ошибка живёт в коде конфигурации, отчёта, обработки или расширения. Лечится она правкой кода, а иногда сбросом пользовательских настроек.
Ниже порядок действий: сначала понять, кто и где упал, потом исправить, потом сделать так, чтобы не падало снова.
Откуда берётся ошибка: пять типовых причин
В скобках платформа называет имя поля. Это главная подсказка: ищите его в тексте модуля и в данных, с которыми работает код.
- 🔤 Опечатка или другой регистр написания в имени реквизита, колонки, ключа структуры. Платформа регистр не различает, а вот лишний пробел или латинская «a» вместо кириллической различает.
- 🧩 Объект другого типа. Вы ждёте документ, а пришёл справочник. Или в переменной лежит ссылка другого вида, у которой нет такого реквизита.
- 🗑️ Поле удалили или переименовали при доработке конфигурации или обновлении типовой. Код, который его использует, остался прежним.
- 📋 Нет колонки в таблице значений или нет ключа в структуре. Колонку добавляют не всегда, а читают её всегда.
- 🔍 Запрос не выбрал поле. В выборке запроса поле не указано, а код читает
Выборка.Поле.
Полезно сразу отделить случаи: падает у всех пользователей или у одного. Если у одного, ищите в его настройках (список, отчёт, форма). Если у всех, виноват код или данные.
Где смотреть: отладчик, журнал и текст сообщения
Сообщение обычно содержит цепочку вызовов: модуль, процедуру и номер строки. Её можно скопировать кнопкой «Подробно» в окне ошибки. Сохраните этот текст целиком, он сэкономит полчаса.
Журнал регистрации
Откройте журнал: Администрирование → Поддержка и обслуживание → Журнал регистрации. Отберите события уровня «Ошибка» за нужное время и пользователя. В комментарии события будет полный текст исключения и стек.
Журнал показывает кто и когда. Но он не покажет значения переменных. Для этого нужен отладчик.
Отладчик в Конфигураторе
- Запустите Конфигуратор для этой базы и включите отладку:
Отладка → Начать отладку. Откроется клиент 1С. - Повторите действие, которое приводит к ошибке.
- Если в настройках отладки включена остановка по ошибке, отладчик остановится на проблемной строке. Если нет, включите в меню отладки остановку по необработанным исключениям.
- Наведите курсор на переменную или откройте окно «Вычислить выражение» и посмотрите, что в ней лежит на самом деле.
Чаще всего за 2 минуты видно: ждали Документ, а там Неопределено, или таблица пришла без нужной колонки.
Если ошибка воспроизводится только у пользователя на рабочей базе, не отлаживайте там. Возьмите копию базы и повторите сценарий на ней.
Что делать без Конфигуратора
Если вы не разработчик и доступа нет, соберите для программиста четыре вещи: полный текст ошибки, действие, после которого она появилась, версию конфигурации и платформы, имя пользователя. По ним находят причину быстрее, чем по фразе «выдаёт ошибку».
Как читать цепочку вызовов
Стек в тексте ошибки идёт сверху вниз: первая строка, это место, где код упал, ниже вызвавшие его процедуры. Начинайте с первой строки, но не останавливайтесь на ней. Часто сама процедура написана верно, а неверные данные ей передали выше по цепочке.
Задайте себе три вопроса:
- Что лежит в переменной, у которой читается поле?
- Кто и откуда её заполнил?
- Менялся ли этот источник за последнее время: запрос, обмен, форма, расширение?
Ответ на третий вопрос обычно и называет виновника. Если менялись сразу несколько вещей, откатывайте по одной на тестовой копии и смотрите, на какой ошибка исчезает.
Запросы и динамические списки
Динамический список строится на запросе. Если в схеме запроса или в настройках остаётся поле, которого уже нет в источнике, форма не откроется или список будет пустым с ошибкой.
Динамический список
- Проверьте свойство «Произвольный запрос» и текст запроса: все ли поля, которые выбираются, ещё есть в таблицах.
- Проверьте «Основную таблицу» списка: если её сменили, пользовательские настройки со старыми полями могут не сойтись.
- Загляните в условное оформление и отборы формы: часто поле остаётся там, когда из списка его уже убрали.
У пользователя в форме списка есть пункт сброса настроек. Он возвращает список к виду по умолчанию. Для всех пользователей сразу проще очистить сохранённые настройки программно, но делать это стоит только в тестовой копии и с согласованием.
Запрос в коде
В тексте запроса поле имеет псевдоним. Выборка читает его по псевдониму, а не по исходному имени:
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Наименование КАК Имя
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Имя); // верно
// Выборка.Наименование -> «Поле объекта не обнаружено»
КонецЦикла;
Здесь Наименование в выборке нет, потому что поле переименовано в Имя. Такая ошибка возникает после правки текста запроса без правки кода, который его читает.
Ещё одна ловушка: поле составного типа. Запрос вернёт ссылку, а реквизит читается через точку уже в коде. Если ссылка пустая или другого вида, реквизита у неё нет или обращение даёт пустое значение. В самом запросе безопаснее использовать ВЫРАЗИТЬ(... КАК Справочник.Имя), когда тип известен заранее.
Безопасный доступ к данным
Если поле может отсутствовать по условиям задачи, проверяйте его до чтения, а не ловите ошибку после.
| Объект | Как проверить | Пример |
|---|---|---|
| Структура | метод Свойство | Если Структура.Свойство("Сумма", Значение) Тогда |
| Таблица значений | поиск колонки | Таблица.Колонки.Найти("Сумма") <> Неопределено |
| Выборка запроса | заранее знать состав полей | поля задаются текстом запроса |
| Ссылка на объект | проверка типа и заполненности | ТипЗнч(Ссылка) = Тип("СправочникСсылка.Контрагенты") |
Пример для структуры. Метод Свойство одновременно проверяет и забирает значение:
Если Параметры.Свойство("Организация", Организация) Тогда
// поле есть, используем Организация
Иначе
Организация = Справочники.Организации.ПустаяСсылка();
КонецЕсли;
Для таблицы значений проверяйте колонку один раз перед циклом, а не в каждой строке.
Когда нужен Попытка…Исключение
Попытка нужна там, где поле вы проверить не можете: данные приходят снаружи, например из файла обмена или от внешней компоненты. Ловите ошибку и пишите понятную запись в журнал:
Попытка
Значение = Данные.Поле;
Исключение
ЗаписьЖурналаРегистрации("Загрузка",
УровеньЖурналаРегистрации.Предупреждение,
, ,
ОписаниеОшибки());
КонецПопытки;
Не оставляйте пустой блок Исключение. Ошибка исчезнет с экрана, а данные молча пропадут. Минимум запись в журнал.
Там, где проверка возможна, она лучше попытки: попытка скрывает и другие ошибки, не только эту.
Расширения и обновления
Расширение живёт поверх основной конфигурации и ссылается на её объекты. Когда поставщик меняет типовую, то поле в расширении может оказаться «в воздухе».
Что проверить после обновления:
- Откройте расширение в Конфигураторе и найдите в его модулях имя поля из ошибки (поиск по конфигурации,
Ctrl+Shift+F). - Посмотрите, существует ли это поле в обновлённой типовой конфигурации. Если нет, нужна доработка расширения под новую структуру.
- Проверьте перехватываемые процедуры. Если типовая процедура изменила состав параметров или передаваемых данных, перехватчик расширения читает не то.
- Проверьте формы: реквизит, добавленный на форму расширением, нужно привязать к данным заново, если основной реквизит изменился.
Отключите расширение на тестовой копии. Если ошибка ушла, виновато оно. Если осталась, проблема в самой конфигурации или данных.
Прежде чем отключать или менять расширения на рабочей базе, сделайте резервную копию и согласуйте работы по регламенту. Правку делайте на копии, потом переносите.
Мини-кейс: после правки запроса отчёт перестал открываться
Разработчик переименовал в запросе отчёта поле Контрагент в Покупатель, чтобы текст читался понятнее. Отчёт на СКД работал, а вот обработка, которая выгружала его результат в файл, начала падать с ошибкой про поле Контрагент.
Как нашли причину:
- Взяли из журнала регистрации стек: падала процедура выгрузки, строка с чтением колонки результата.
- В отладчике открыли таблицу значений с результатом и увидели, что колонки
Контрагентв ней уже нет. - Поиском по конфигурации нашли ещё два места, где читалось то же имя: макет печати и регламентное задание.
Исправили во всех трёх местах и добавили проверку колонки перед чтением. Урок простой: у любого переименованного поля обычно больше читателей, чем кажется. Одна строка в одном модуле почти никогда не единственная.
Фоновые и регламентные задания: ошибка без окна
Бывает, что на экране ничего не видно. Падает регламентное задание или фоновая выгрузка, а пользователь замечает только, что данные не обновились. Признаки такой ошибки: задание завершается с ошибкой, а результат не появился.
Что делать:
- Откройте журнал регистрации и отберите события по имени задания или по пользователю, под которым оно запускается.
- Посмотрите, какая процедура вызвалась последней перед сбоем. Её и открывайте в модуле.
- Запустите ту же процедуру вручную в отладчике на копии базы с теми же параметрами.
- Если параметры берутся из константы или настройки, проверьте их содержимое: иногда структура параметров сохранена старой версией кода и в ней нет нового ключа.
Последний пункт встречается часто. Код обновили и стал ждать ключ НовыйПараметр, а сохранённая структура создана до обновления. Проверка через метод Свойство из раздела выше решает это сразу.
Как избежать повторения
Одна исправленная строка не решает проблему. Нужна привычка, которая снижает шанс ошибки при следующих доработках.
Практические приёмы:
- 🔎 Поиск по конфигурации перед переименованием. Ищите не только по коду, но и по запросам, макетам СКД, условному оформлению и правам.
- 🧪 Синтаксический контроль.
Конфигурация → Проверка конфигурацииловит часть обращений к несуществующим реквизитам, но не все: динамические обращения по строковому имени проверка не видит. - 🧱 Не обращайтесь к полям по строке без нужды. Конструкция вроде
Объект[ИмяПоля]удобна, но опечатка в строке всплывёт только при выполнении. - 📝 Единое место для списка полей. Если набор колонок используется в нескольких процедурах, соберите его в одну функцию.
- 🕐 Тестовая копия после каждого обновления. Одно открытие основных списков и отчётов на копии выявляет большую часть таких сбоев.