К статье
Практический материал

Разработка и Конфигурация · 11 мин

Ошибка 1С «Поле объекта не обнаружено»: как найти причину и исправить

Разбираем ошибку 1С «Поле объекта не обнаружено»: причины в коде, формах и обменах, пошаговое исправление в конфигураторе, проверка результата и типичные ошибки.

Ошибка «Поле объекта не обнаружено» в 1С возникает, когда программный код обращается к свойству, реквизиту или полю, которого нет у конкретного объекта в момент выполнения. Типичный пример: код пытается прочитать Документ.Номенклатура, а у этого вида документа такого реквизита нет, либо переменная содержит не тот тип данных, который ожидал разработчик.

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

Чаще всего проблема появляется после обновления конфигурации, доработки кода, изменения структуры метаданных или при работе с универсальными механизмами обмена, где состав полей определяется динамически. Ниже разобраны основные причины и конкретные способы устранения для каждого сценария.

Как понять, где именно возникает ошибка

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

Для отладки запустите конфигуратор, подключитесь к нужной информационной базе через меню «Отладка → Подключение», установите точку останова в предполагаемом модуле и повторите действие, вызывающее ошибку. Когда выполнение остановится, откройте табло (Shift+F9) и проверьте тип переменной, к которой идёт обращение: команда ТипЗнч(Объект) покажет реальный тип значения.

Частая ситуация: переменная должна содержать ссылку на документ, но фактически содержит строку, число или значение Неопределено. Тогда любое обращение к реквизиту даст именно эту ошибку. Проверка типа перед обращением — обязательный приём при разборе таких случаев.

Ошибка при открытии формыПроблема в модуле формы или реквизитах формы

Проверить обработчики ПриСозданииНаСервере и ПриОткрытии

Ошибка при проведении документаПроблема в модуле объекта или подписках на события

Проверить ОбработкаПроведения и подписки на события

Ошибка при обмене даннымиНесовпадение структуры объектов в базах

Сверить состав реквизитов в источнике и приёмнике

Опечатка или переименование реквизита

Самая простая причина — имя поля в коде не совпадает с именем реквизита в метаданных. Встроенный язык 1С регистронезависим, но чувствителен к точному написанию: СуммаДокумента и СуммаДокумета — разные имена, и вторая версия вызовет ошибку.

Откройте конфигуратор, найдите объект метаданных (документ, справочник, регистр) и сверьте имя реквизита с тем, что используется в коде. Удобно скопировать имя прямо из палитры свойств, чтобы исключить опечатку. Если реквизит недавно переименовывали, выполните поиск по всей конфигурации (Правка → Глобальная замена или Ctrl+Shift+F) по старому имени — так найдутся все места, где оно ещё используется.

Особое внимание уделите реквизитам табличных частей. Обращение вида СтрокаТЧ.Цена вызовет ошибку, если поле «Цена» есть в одной табличной части документа, но отсутствует в другой, а код универсально обходит обе.

Объект не того типа: проверка перед обращением

Вторая по частоте причина — код ожидает один тип, а получает другой. Например, функция возвращает Неопределено, если документ не найден, а вызывающий код сразу обращается к реквизиту результата. Или параметр процедуры может принимать ссылку на разные виды документов, не у всех из которых есть нужный реквизит.

Защитный шаблон выглядит так: сначала проверяется тип значения, затем выполняется обращение к полю. Пример:

Если ТипЗнч(Объект) = Тип("ДокументОбъект.РеализацияТоваровУслуг") Тогда

Сумма = Объект.СуммаДокумента;

ИначеЕсли Объект = Неопределено Тогда

Возврат;

КонецЕсли;

Для составных типов (параметр может быть ссылкой на несколько видов документов) проверяйте наличие реквизита через метаданные: Объект.Метаданные().Реквизиты.Найти("СуммаДокумента"). Если поиск вернул Неопределено, реквизита у этого вида объекта нет, и обращаться к нему нельзя.

Ошибки при работе со структурами и данными формы

Структуры и соответствия

Если код обращается к свойству структуры, которого нет, возникает та же ошибка. Перед чтением используйте метод Свойство: Если Структура.Свойство("Сумма", ЗначениеСуммы) Тогда ... КонецЕсли;. Такой приём безопасен: если ключа нет, выполнение просто не зайдёт в ветку, а ошибки не будет.

Похожая ситуация с соответствиями: обращение по несуществующему ключу возвращает Неопределено, и последующее чтение поля этого значения даст ошибку. Всегда проверяйте результат Соответствие.Получить(Ключ) на Неопределено перед использованием.

Данные формы и динамические списки

При работе на управляемой форме ошибка часто связана с реквизитами формы: код обращается к Объект.Реквизит, а реквизит формы с таким именем не создан или основной реквизит формы имеет другой тип. Проверьте список реквизитов в редакторе формы и убедитесь, что обращение идёт к существующему элементу дерева реквизитов.

Если на форме используется динамический список с произвольным запросом, убедитесь, что поле, по которому настроена сортировка или отбор, присутствует в выборке запроса. Отсутствующее в запросе поле — типичный источник ошибки при открытии формы списка.

Ошибка после обновления конфигурации

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

Проверьте журнал регистрации на наличие ошибок обновления и убедитесь, что все обработчики отложенного обновления завершены (в типовых конфигурациях — раздел «Результаты обновления программы»). Если доработки вынесены в расширение, откройте его в конфигураторе и проверьте заимствованные реквизиты и методы: после обновления основной конфигурации ссылки расширения могут стать недействительными.

При прямых доработках конфигурации выполните сравнение и объединение с конфигурацией поставщика и проанализируйте изменённые объекты: какие реквизиты удалены или переименованы. Затем глобальным поиском найдите в доработанном коде обращения к этим именам и исправьте их.

Ошибка при обмене данными и в внешних обработках

При обмене через правила конвертации (КД) или универсальный формат ошибка означает, что в базе-приёмнике или источнике структура объекта отличается от той, на которую рассчитаны правила. Например, правило обращается к реквизиту «Договор», а в приёмнике этот реквизит удалён или переименован. Решение — синхронизировать версии конфигураций в обеих базах или скорректировать правила обмена.

Во внешних обработках и отчётах, написанных под конкретную конфигурацию, ошибка возникает при запуске в базе с другой версией или другой конфигурацией. Универсальные обработки должны проверять наличие метаданных перед обращением: Метаданные.Документы.Найти("ЗаказКлиента") и далее проверку реквизитов. Если обработка «жёстко» привязана к именам, она будет падать в любой базе, где этих имён нет.

Отдельный случай — программное создание объекта через СоздатьЭлемент() или СоздатьДокумент() с последующим заполнением реквизитов. Если код заполнения писался под другую версию конфигурации, часть присваиваний может обращаться к несуществующим полям. Исправляется тем же способом: сверкой имён с метаданными и добавлением проверок.

Порядок действий при исправлении
  1. 1
    Скопируйте полный текст ошибки и имя поля из сообщения
  2. 2
    Найдите место обращения к полю через отладчик или глобальный поиск
  3. 3
    Проверьте тип объекта в момент ошибки через ТипЗнч()
  4. 4
    Сверьте имя поля с метаданными объекта в конфигураторе
  5. 5
    Исправьте имя или добавьте проверку типа и наличия реквизита
  6. 6
    Протестируйте сценарий на копии базы, затем перенесите в рабочую

Проверка результата и профилактика

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

Для профилактики полезны три приёма. Первый — защитное программирование: проверка типа и наличия реквизита перед обращением в любом универсальном коде. Второй — использование синтакс-помощника и контекстной подсказки конфигуратора, которые показывают реальный состав свойств объекта. Третий — тестирование доработок на копии базы с реальными данными перед переносом в рабочую среду.

Если ошибка возникает периодически и только у части пользователей, проверьте права доступа: ограничение на уровне записей (RLS) может приводить к тому, что запрос возвращает неполный набор полей, и код, обращающийся к отсутствующему в выборке полю, падает. В таком случае поле нужно явно добавить в запрос или пересмотреть логику обработки результата.

Типичные ошибки
01
Исправление только одного места обращения к полю — после переименования реквизита старое имя часто остаётся в нескольких модулях; используйте глобальный поиск
02
Проверка результата только на одном документе — универсальный код падает на другом виде документов, где реквизита нет
03
Игнорирование значения Неопределено — обращение к полю пустого значения даёт ту же ошибку, что и обращение к несуществующему реквизиту
04
Перенос исправления в рабочую базу без теста на копии — велик риск сломать смежные сценарии
Итог

Что важно запомнить

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

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

Ошибка появляется только у одного пользователя. В чём причина?

Чаще всего дело в правах доступа или настройках: из-за RLS запрос возвращает меньше полей, либо у пользователя отличается функциональная опция, меняющая состав реквизитов на форме. Сравните права проблемного пользователя с теми, у кого ошибки нет, и проверьте журнал регистрации под его сеансом.

Можно ли исправить ошибку без конфигуратора?

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

Ошибка возникла после обновления, доработок в базе нет. Что делать?

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

Как найти все места, где используется конкретный реквизит?

В конфигураторе выделите реквизит в дереве метаданных и выполните «Поиск ссылок в объектах» из контекстного меню — будут найдены все модули, где встречается имя. Дополнительно полезен глобальный поиск по имени (Ctrl+Shift+F) с включённым поиском по всей конфигурации.

Ошибка в запросе — это та же проблема?

Нет, у запросов другое сообщение: «Поле не найдено» с указанием текста запроса. Оно означает, что в запросе используется поле, отсутствующее в таблице-источнике. Исправляется редактированием текста запроса: сверкой имён полей с реквизитами таблицы в конструкторе запроса.

Как защититься от такой ошибки в универсальной обработке?

Перед обращением к метаданным проверяйте их наличие через Метаданные.НайтиПоПолномуИмени() или методы Найти() коллекций, а наличие реквизита — через Метаданные().Реквизиты.Найти(). Для структур используйте метод Свойство(), для соответствий — проверку результата Получить() на Неопределено.