Как исправить ошибку «Поле объекта не обнаружено (СтавкаНДС)» в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Анализ исходного кода и причины возникновения ошибки

Проанализируем пример кода управляемой формы документа, в котором происходит ошибка:


&НаКлиенте
Процедура ТоварыНоменклатураПриИзменении(Элемент)
    ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
    ТекущиеДанные.СтавкаНДС = ПолучитьСтавкуНДСНоменклатуры(ТекущиеДанные.Номенклатура);
    РассчитатьСуммуТабличнойЧастиТовары();
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьСтавкуНДСНоменклатуры(Номенклатура)
    Возврат Номенклатура.СтавкаНДС; 
КонецФункции

В момент выполнения строки Возврат Номенклатура.СтавкаНДС; платформа генерирует исключение. Это происходит по одной из следующих основных причин:

  1. Отсутствие реквизита в объекте метаданных. В справочнике Номенклатура действительно нет реквизита с именем СтавкаНДС. Возможно, при создании он был назван иначе (например, СправочникНДС, СтавкаНДСНоменклатуры) или его забыли добавить.
  2. Обращение к пустой ссылке или `Неопределено`. Если переменная Номенклатура не заполнена или передаваемый объект не является ссылкой на справочник, обращение через точку к реквизиту вызовет ошибку.
  3. Несоответствие типов. Передаваемый в функцию параметр может иметь тип Строка, Структура или другой неподходящий тип данных, у которого нет свойства СтавкаНДС.

Шаг 1. Проверка состава реквизитов в Конфигураторе

Первым делом откроем Конфигуратор и проанализируем дерево конфигурации:

  1. Найдем справочник Номенклатура и раскроем ветку Реквизиты.
  2. Убедимся, что реквизит с точным именем СтавкаНДС существует. Обратим внимание на регистр букв и отсутствие опечаток.
  3. Если реквизит назван по-другому, переименуем его в конфигураторе или скорректируем имя реквизита в программном коде.

Шаг 2. Корректировка кода и добавление проверок

Чтобы избежать критических ошибок при очистке строки или выборе незаполненной номенклатуры, добавим необходимые проверки на клиенте и на сервере.

Рассмотрим обновленный вариант процедур:


&НаКлиенте
Процедура ТоварыНоменклатураПриИзменении(Элемент)
    ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
    
    // Проверяем наличие активной строки табличной части
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    ТекущиеДанные.СтавкаНДС = ПолучитьСтавкуНДСНоменклатуры(ТекущиеДанные.Номенклатура);
    РассчитатьСуммуТабличнойЧастиТовары();
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьСтавкуНДСНоменклатуры(Номенклатура)
    // Проверяем заполненность и тип передаваемого параметра
    Если ЗначениеЗаполнено(Номенклатура) И ТипЗнч(Номенклатура) = Тип("СправочникСсылка.Номенклатура") Тогда
        Возврат Номенклатура.СтавкаНДС;
    Иначе
        Возврат Неопределено;
    КонецЕсли;
КонецФункции

Шаг 3. Дополнительные технические причины и способы их устранения

Если реквизит существует в Конфигураторе, а код содержит все необходимые проверки, но ошибка продолжается, проанализируем менее очевидные факторы:

1. Кэш платформы и динамическое обновление
При использовании динамического обновления информационной базы сеанс пользователя может использовать устаревший кэш метаданных. В таком случае платформа «не видит» вновь созданные реквизиты. Для решения проблемы следует перезапустить сеанс с параметром запуска /ClearCache или полностью очистить локальный кэш пользователя.

2. Права доступа и ограничения RLS
Если у текущего пользователя или его роли отсутствуют права на чтение конкретного реквизита СтавкаНДС, платформа воспринимает это поле как несуществующее. Посмотрим права роли в Конфигураторе или перейдем в привилегированный режим, если получение значения происходит в сервером коде:


УстановитьПривилегированныйРежим(Истина);
Ставка = Номенклатура.СтавкаНДС;

3. Связь элементов управляемой формы
В управляемых формах переменная Элементы.Товары.ТекущиеДанные возвращает объект типа ДанныеФормыЭлементКоллекции. Проверим на вкладке «Реквизиты» редактора формы, включен ли реквизит СтавкаНДС в состав реквизитов табличной части Объект.Товары и заполнено ли свойство ПутьКДанным у элемента формы.

Шаг 4. Оптимизация работы с реквизитами через точку

Обращение к реквизитам объекта через точку (например, Номенклатура.СтавкаНДС) заставляет платформу считывать весь объект из базы данных в память сервера. Для повышения производительности рекомендуем использовать функции Библиотеки Стандартных Подсистем (БСП) или прямой запрос:

Вариант с использованием функции БСП:


&НаСервереБезКонтекста
Функция ПолучитьСтавкуНДСНоменклатуры(Номенклатура)
    Если Не ЗначениеЗаполнено(Номенклатура) Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    Возврат ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Номенклатура, "СтавкаНДС");
КонецФункции

Вариант с прямым запросом к базе данных:


&НаСервереБезКонтекста
Функция ПолучитьСтавкуНДСНоменклатуры(Номенклатура)
    Если Не ЗначениеЗаполнено(Номенклатура) Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	Номенклатура.СтавкаНДС КАК СтавкаНДС
        |ИЗ
        |	Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |	Номенклатура.Ссылка = &Ссылка";
    
    Запрос.УстановитьПараметр("Ссылка", Номенклатура);
    Выборка = Запрос.Выполнить().Выбрать();
    
    Если Выборка.Следующий() Тогда
        Возврат Выборка.СтавкаНДС;
    КонецЕсли;
    
    Возврат Неопределено;
КонецФункции

Использование запросов или методов БСП позволяет снизить нагрузку на сервер базы данных и исключает проблемы с некорректным считыванием тяжелых объектов из памяти.

← На главную