Как найти строку кода, где 1С не видит поле, и что в ней поправить
Содержание
Ошибка Поле объекта не обнаружено (Склад) в 1С значит одно: код обратился через точку к свойству, которого у этого объекта в момент выполнения нет. В скобках платформа пишет имя поля, а в фигурных скобках перед текстом — модуль и номер строки. Решение почти всегда в этой строке: поле переименовали, удалили, не передали на клиент или обращаются к нему у объекта другого типа.
Ошибка возникает только во время работы программы, а не при сохранении конфигурации. Поэтому её часто видят бухгалтеры после обновления или установки внешней обработки, хотя виноват код, а не данные. Базу при этом чинить не нужно: она цела.
Почему 1С выдаёт «Поле объекта не обнаружено»
Встроенный язык 1С позволяет писать Объект.ИмяПоля, не зная заранее тип объекта. Проверка, есть ли такое поле, происходит только в момент выполнения строки. Если у конкретного значения такого свойства нет, платформа останавливает код и выдаёт эту ошибку.
Важно отличать её от похожих сообщений:
| Текст ошибки | Где возникает | Что значит |
|---|---|---|
Поле объекта не обнаружено (Имя) | Код модуля | У объекта нет свойства с таким именем |
Поле не найдено "Т.Имя" | Текст запроса | В источнике запроса нет такого поля |
Значение не является значением объектного типа (Имя) | Код модуля | Переменная пустая (Неопределено) или примитивная, полей у неё нет вообще |
Переменная не определена (Имя) | Код модуля | Обращение к переменной, а не к полю |
Если в сообщении именно «Поле объекта не обнаружено», значит сам объект существует. Пустую ссылку или Неопределено тут искать не надо — ищите несовпадение имени или типа.
Как расшифровать текст ошибки и найти строку
Полное сообщение выглядит так:
{Документ.РеализацияТоваровУслуг.МодульОбъекта(245)}: Поле объекта не обнаружено (СкладОтгрузки)
Разбираем по частям:
- 📍
Документ.РеализацияТоваровУслуг.МодульОбъекта— модуль, где упал код. Это может быть модуль формы, общий модуль, модуль менеджера или внешней обработки (ВнешняяОбработка.Имя.Форма.Форма.Форма). - 🔢
(245)— номер строки в этом модуле. - 🏷️
СкладОтгрузки— имя поля, которое не нашлось.
Что сделать пользователю без доступа к Конфигуратору
- В окне ошибки нажмите ссылку Подробнее или кнопку отчёта об ошибке. Скопируйте весь текст, включая стек вызовов.
- Запишите, какое действие вызвало ошибку: проведение, печать, открытие формы, запуск обработки.
- Откройте
Администрирование → Обслуживание → Журнал регистрации, отберите события с уровнем «Ошибка» за нужное время. Там будет тот же текст с пользователем и объектом. - Передайте это программисту. С именем модуля и номером строки он найдёт причину за минуты.
Что сделать программисту
- Откройте Конфигуратор, найдите модуль из сообщения и перейдите к строке через
Ctrl+G. - Если причина не очевидна, включите
Отладка → Остановка по ошибкеи запустите отладку (F5). - Повторите действие. Отладчик остановится на строке с ошибкой, а в табло (
Shift+F9) можно посмотреть реальный тип объекта:ТипЗнч(Объект).
В коде с обработкой исключений полный текст удобно писать в журнал:
Попытка
ВыполнитьВыгрузку(Параметры);
Исключение
ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации("Выгрузка данных", УровеньЖурналаРегистрации.Ошибка, , , ТекстОшибки);
ВызватьИсключение;
КонецПопытки;
ПодробноеПредставлениеОшибки сохраняет модуль, строку и стек. КраткоеПредставлениеОшибки даёт только текст, его показывают пользователю.
Типовые причины в коде и метаданных
Само сообщение одно, но причин несколько. Разберём их по частоте в реальных базах.
Опечатка или переименованный реквизит
Самый простой случай. В коде написано Объект.СкладОтгрузки, а реквизит называется Склад. Или реквизит переименовали в метаданных, а в одном из модулей старое имя осталось.
💡 Найти все упоминания старого имени: Правка → Глобальный поиск (Ctrl+Shift+F) по всей конфигурации, включая модули форм.
Составной тип и чужой документ
Поле Регистратор регистра или реквизит составного типа может содержать ссылки на разные документы. У поступления есть реквизит Контрагент, а у ввода остатков или операции его может не быть. Код Движение.Регистратор.Контрагент работает на одних документах и падает на других.
Правильно — сначала проверить тип:
Если ТипЗнч(Движение.Регистратор) = Тип("ДокументСсылка.ПоступлениеТоваровУслуг") Тогда
Контрагент = Движение.Регистратор.Контрагент;
Иначе
Контрагент = Неопределено;
КонецЕсли;
Структура без нужного ключа
Структура, параметры формы и параметры процедур часто собираются в разных местах. Если один вызов не положил ключ, обращение Параметры.Склад вызовет ту же ошибку.
Безопасное чтение:
Склад = Неопределено;
Если ДопПараметры.Свойство("Склад", Склад) Тогда
// ключ есть, значение уже в переменной Склад
КонецЕсли;
Колонка таблицы или поле выборки
Строка ТаблицыЗначений и выборка запроса содержат только те колонки, которые в них есть. Добавили поле в обработку, но забыли в ВЫБРАТЬ — Выборка.Поле упадёт. Здесь ошибка не в запросе, а в коде после него.
Табличная часть вместо её строки
Частая ошибка начинающих: Объект.Товары.Номенклатура. У табличной части нет поля Номенклатура — оно есть у каждой её строки. Платформа честно сообщает «Поле объекта не обнаружено (Номенклатура)».
Нужно перебрать строки или взять конкретную:
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
Если Не ЗначениеЗаполнено(СтрокаТЧ.Номенклатура) Тогда
Сообщить("Не заполнена номенклатура в строке " + Формат(СтрокаТЧ.НомерСтроки, "ЧГ=0"));
КонецЕсли;
КонецЦикла;
То же самое с результатом НайтиСтроки(): он возвращает массив строк, а не одну строку. Обращение к полю у массива даст ту же ошибку — сначала проверьте, что массив не пуст, и возьмите элемент [0].
Обращение к реквизиту ссылки на клиенте
На клиенте у ссылки нельзя прочитать реквизиты через точку. Код Объект.Договор.Владелец в процедуре с &НаКлиенте даст «Поле объекта не обнаружено (Владелец)». Значение нужно получить на сервере:
&НаКлиенте
Процедура ДоговорПриИзменении(Элемент)
Контрагент = ВладелецДоговора(Объект.Договор);
КонецПроцедуры
&НаСервереБезКонтекста
Функция ВладелецДоговора(Договор)
Возврат ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Договор, "Владелец");
КонецФункции
ОбщегоНазначения.ЗначениеРеквизитаОбъекта есть в типовых конфигурациях на БСП. Она читает одно поле запросом и не тянет весь объект.
Динамические списки и формы: где поля «пропадают»
В управляемых формах эта ошибка встречается чаще всего, потому что на клиент передаются не все данные.
Поле не попало в ТекущиеДанные
Элементы.Список.ТекущиеДанные содержит только поля, которые выведены в колонки или отмечены особым флагом. Если колонку убрали с формы, код Элементы.Список.ТекущиеДанные.Организация начнёт падать.
Как исправить:
- Откройте форму в Конфигураторе, вкладка Реквизиты.
- Раскройте реквизит
Список(типДинамическийСписок). - У нужного поля поставьте флажок в колонке Использовать всегда.
После этого поле будет приходить на клиент, даже если пользователь скрыл колонку в настройках.
Перед обращением к ТекущиеДанные проверяйте их на Неопределено — если строка не выделена, полей нет совсем, и ошибка будет уже другая.
Произвольный запрос динамического списка
Если у списка включён произвольный запрос, в нём должно быть каждое поле, которое использует код. Добавили в обработчик ПриПолученииДанныхНаСервере чтение Строка.Данные.Ответственный — поле Ответственный должно быть в тексте запроса списка.
Элементы и реквизиты формы
- 🧩
Элементы.ИмяЭлемента— элемент удалили или переименовали в редакторе формы, а код остался. - 📄
Объект.Реквизит— реквизит добавлен расширением, а расширение отключено или не применилось. - 📦 Реквизит формы создаётся программно через
ИзменитьРеквизиты(), но код обращается к нему раньше этой строки.
Обновления, расширения и совместимость
После обновления типовой конфигурации ошибка обычно сидит не в самой типовой, а в том, что к ней прикручено.
| Где искать | Где это в программе | Что проверить |
|---|---|---|
| Расширения | Администрирование → Печатные формы, отчеты и обработки → Расширения | Нет ли предупреждения о применимости; совпадают ли заимствованные объекты с новым релизом |
| Внешние обработки и печатные формы | Администрирование → Печатные формы, отчеты и обработки → Дополнительные отчеты и обработки | Какая из них запускалась при ошибке — имя будет в тексте сообщения |
| Доработки в основной конфигурации | Конфигуратор, сравнение с поставкой | Какие реквизиты изменились в новом релизе |
Порядок проверки:
- По имени модуля из сообщения определите, чей это код:
ВнешняяОбработка...— внешняя обработка; модуль объекта, заимствованного в расширение, — проверьте расширение; остальное — сама конфигурация. - Если виновато расширение, временно снимите флажок Активно и повторите действие. Отключение расширения затронет всех пользователей базы, делайте это в нерабочее время или на копии.
- Если ошибка ушла, расширение надо адаптировать под новый релиз: обновить его от разработчика или поправить имена полей.
- Для внешней обработки запросите версию под ваш релиз конфигурации.
Не откатывайте обновление ради одной ошибки. Сначала проверьте доработки: откат на старую копию потеряет данные, введённые после обновления.
Отдельный случай — режим совместимости. Если в свойствах конфигурации установлен режим совместимости со старой версией платформы, часть новых свойств объектов платформы недоступна. Код, написанный под новую платформу, может получить ту же ошибку на свойстве системного объекта, а не реквизита.
Почему проверка конфигурации её не находит
Конфигурация → Проверка конфигурации ловит ошибки, когда тип объекта известен при компиляции. Если поле читают у переменной, тип которой станет ясен только при выполнении, проверка промолчит. Поэтому после доработок нужен ручной прогон сценариев на копии базы.
Как устранить ошибку и не допустить её снова
Короткий алгоритм для любого случая:
- Прочитайте имя модуля, номер строки и имя поля из сообщения.
- Найдите строку и посмотрите, к какому объекту обращаются.
- Узнайте реальный тип объекта в отладчике.
- Сравните с метаданными: есть ли такое поле у этого типа.
- Исправьте: имя, проверку типа, передачу данных на клиент или флаг «Использовать всегда».
- Проверьте на копии базы все сценарии, где вызывается этот код.
Приёмы защитного кода
Чтение поля, которое может отсутствовать, без исключения:
Значения = Новый Структура("Склад, Ответственный");
ЗаполнитьЗначенияСвойств(Значения, ДанныеСтроки);
// если у ДанныеСтроки нет поля Склад, Значения.Склад останется Неопределено
ЗаполнитьЗначенияСвойств копирует только совпадающие свойства и не падает на отсутствующих.
Проверка наличия реквизита в метаданных:
ЕстьРеквизит = Метаданные.Справочники.Номенклатура.Реквизиты.Найти("Артикул") <> Неопределено;
💡 Коллекция Реквизиты не содержит стандартных реквизитов вроде Код и Наименование. Для них есть отдельная коллекция СтандартныеРеквизиты.
Профилактика в команде
- ✅ Переименовывать реквизиты только с глобальным поиском по старому имени.
- ✅ В расширениях и внешних обработках читать поля типовых объектов через функции БСП, а не через точку по цепочке.
- ✅ Для составных типов всегда проверять
ТипЗнчперед обращением к полю. - ✅ После каждого обновления прогонять ключевые доработки на копии базы до переноса в рабочую.