Как исправить ошибку «Поле объекта не обнаружено» при работе с отбором регистра сведений?

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

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

Разбор основной причины: внимательность к псевдонимам запроса

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


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

Причина ошибки в данном случае максимально проста, но труднозаметна при беглом просмотре: опечатка в псевдониме поля запроса. В тексте запроса поле названо ОсновноеСредсто (пропущена буква «в»), а в цикле при обращении к результату выборки используется правильное написание Рез.ОсновноеСредство.

В системе 1С:Предприятие объект ВыборкаИзРезультатаЗапроса динамически формирует свои свойства на основании колонок, возвращаемых запросом. Если в запросе указан псевдоним с ошибкой, то и в выборке будет поле с этой ошибкой. Обращение к несуществующему свойству объекта Рез и вызывает исключение.

Ограничения программной установки отбора в наборе записей

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

Проанализируем правила работы с объектом РегистрСведенийНаборЗаписей:

  1. Отбор только по измерениям: Программная установка фильтра в наборе записей возможна исключительно по тем полям, которые являются измерениями регистра в метаданных.
  2. Отбор по периоду: Для периодических регистров сведений в Отбор всегда доступно поле Период.
  3. Ресурсы и реквизиты: Если вы попытаетесь написать Набор.Отбор.МойРесурс.Установить(Значение), система выдаст ошибку «Поле объекта не обнаружено», так как ресурсы и реквизиты не могут входить в состав ключа записи и, соответственно, по ним нельзя построить набор.

Оптимизация производительности: работа с объектами в цикле

Посмотрим на структуру кода автора с точки зрения производительности. Создание объекта СоздатьНаборЗаписей() внутри цикла Пока Рез.Следующий() является классическим антипаттерном. Каждый вызов этого метода заставляет систему выделять память под новый объект и инициализировать его структуру.

Рассмотрим, как правильно организовать такой процесс:


// Правильный подход: инициализируем объект один раз вне цикла
НаборЗаписей = РегистрыСведений.СтавкиНалогаНаИмуществоПоОтдельнымОсновнымСредствам.СоздатьНаборЗаписей();

Пока Рез.Следующий() Цикл
    // Очищаем предыдущие отборы, если необходимо (хотя Установить() заменяет старое значение)
    НаборЗаписей.Отбор.ОсновноеСредство.Установить(Рез.ОсновноеСредство);
    
    НаборЗаписей.Прочитать();
    
    Для Каждого СтрИзНабора Из НаборЗаписей Цикл
        СтрИзНабора.НеПодлежитНалогообложению = Ложь;
    КонецЦикла;
    
    Если НаборЗаписей.Модифицирован() Тогда
        НаборЗаписей.Записать();
    КонецЕсли;
КонецЦикла;

В данном примере мы экономим ресурсы сервера, переиспользуя один и тот же экземпляр объекта набора записей для каждой итерации цикла.

Логическая ловушка при использовании СрезаПоследних

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

Если в регистре ведется история изменений (например, ставка налога менялась ежегодно), то СрезПоследних вернет только одну — самую свежую запись. Установив отбор только по ОсновноеСредство и выполнив Прочитать(), вы прочитаете все записи из истории по этому ОС. Если вы затем измените их и запишете набор, всё будет в порядке. Однако, если вы планировали изменить только актуальную запись, ваш код может затронуть исторические данные.

Рекомендация: Если нужно точечное изменение конкретной записи за конкретную дату, всегда добавляйте в запрос поле Период и устанавливайте его в отборе набора записей:

НаборЗаписей.Отбор.Период.Установить(Рез.Период);

Альтернативный способ: использование Менеджера записи

Когда требуется изменить или создать строго одну запись в регистре сведений, удобнее и безопаснее использовать МенеджерЗаписи вместо НабораЗаписей. Это избавляет от необходимости обходить коллекцию в цикле Для Каждого.

Разберем пример реализации через менеджер:


МенеджерЗаписи = РегистрыСведений.СтавкиНалогаНаИмуществоПоОтдельнымОсновнымСредствам.СоздатьМенеджерЗаписи();

Пока Рез.Следующий() Цикл
    // Заполняем значения всех измерений и период для поиска конкретной записи
    МенеджерЗаписи.Период = Рез.Период;
    МенеджерЗаписи.ОсновноеСредство = Рез.ОсновноеСредство;
    
    МенеджерЗаписи.Прочитать(); // Загружаем данные из БД
    
    Если МенеджерЗаписи.Выбран() Тогда
        МенеджерЗаписи.НеПодлежитНалогообложению = Ложь;
        МенеджерЗаписи.Записать();
    КонецЕсли;
КонецЦикла;

Этот метод более «чистый», когда речь идет о редактировании единичных строк, так как МенеджерЗаписи работает аналогично объекту справочника или документа.

Особенности регистра ставок налога на имущество

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

Простое изменение признака НеПодлежитНалогообложению напрямую в регистре может не привести к мгновенному пересчету уже начисленных налогов. После выполнения подобных обработок рекомендуется:

  1. Проверить актуальность записей в связанных регистрах-расчетах.
  2. Перепровести документы «Закрытие месяца», отвечающие за расчет налога на имущество.
  3. Убедиться, что изменения отразились в декларации по налогу на имущество (путем перезаполнения отчета).

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

← На главную