При активном использовании расширений в платформе 1С предприятия разработчики часто сталкиваются с ситуацией, когда стандартные конфигурации дополняются новыми реквизитами. Например, к справочнику ФизическиеЛица добавляется реквизит Должность. Однако при попытке вывести это поле во внешнем отчете или обработке система внезапно генерирует ошибку: «Поле объекта не обнаружено (Должность)». Примечательно, что еще вчера отчет мог работать корректно, а сегодня отказывается функционировать.
В этой статье мы подробно разберем причины возникновения данной проблемы, проанализируем типичные ошибки в коде и рассмотрим несколько эффективных способов решения, которые помогут вернуть работоспособность вашему отчету.
Прежде чем переходить к исправлению кода, давайте разберемся, почему платформа 1С ведет себя подобным образом. Взаимодействие внешних файлов (отчетов .erf и обработок .epf) с метаданными расширений имеет ряд архитектурных особенностей:
Ссылка.РеквизитРасширения платформа пытается выполнить неявный запрос к базе данных. В контексте внешнего отчета этот механизм часто дает сбой.Проанализируем типичный сценарий, с которым столкнулся автор темы. В коде отчета присутствует запрос, который успешно получает данные:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Калькуляция1.Подписант КАК Подписант,
| Калькуляция1.Подписант.Должность КАК Должность
|ИЗ
| Документ.Калькуляция КАК Калькуляция1";
Обратите внимание, что в самом запросе поле Должность получается абсолютно корректно. Однако далее при выводе данных в макет совершается критическая ошибка:
ОбластьПодвал.Параметры.Должность1 = Подписант.Должность;
В данном случае переменная Подписант содержит объект типа СправочникСсылка.ФизическиеЛица. Попытка обратиться к реквизиту Должность через точку от этой ссылки приводит к ошибке «Поле объекта не обнаружено», так как для платформы в текущем контексте выполнения ссылка не содержит этого свойства.
Поскольку поле Должность уже было успешно получено и обработано СУБД внутри тела запроса, нам нет никакой необходимости обращаться к нему повторно через ссылку. Мы должны извлечь готовое значение из результата выборки запроса. Рассмотрим правильный пример обхода выборки:
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Неправильно: ОбластьПодвал.Параметры.Должность1 = ВыборкаДетальныеЗаписи.Подписант.Должность;
// Правильно: берем значение, которое уже выбрано в колонку «Должность»
ОбластьПодвал.Параметры.Должность1 = ВыборкаДетальныеЗаписи.Должность;
КонецЦикла;
Этот способ решает проблему сразу в двух направлениях. Во-первых, он устраняет ошибку обращения к несуществующему (для ссылки) полю объекта. Во-вторых, он колоссально оптимизирует скорость работы отчета, избавляя СУБД от сотен дополнительных неявных микрозапросов при выводе каждой строки макета.
Если код написан верно, но отчет все равно выдает ошибку, вероятнее всего, дело в безопасном режиме БСП. Чтобы исправить это, выполним следующие шаги в режиме «1С:Предприятие»:
Если отчет планируется использовать постоянно и он жестко завязан на реквизиты, добавленные в расширении, то лучшим архитектурным решением будет отказаться от концепции внешнего файла .erf. Перенесем отчет внутрь расширения:
После этого отчет станет частью единой информационной системы, будет иметь полный доступ ко всем добавленным реквизитам «из коробки» и перестанет зависеть от ограничений безопасного режима внешних обработок.
Бывают ситуации, когда ошибка появляется внезапно без изменения кода (например, «вчера все работало»). Это может быть связано с тем, что платформа закэшировала старую структуру метаданных справочника ФизическиеЛица и при запуске внешнего отчета обращается к неактуальным адресам памяти. Для решения этой проблемы выполним очистку кэша:
Разработчики фирмы «1С» знают о неудобствах, связанных с невидимостью расширенных реквизитов во внешних файлах. Начиная с будущих релизов платформы (анонсировано в версии 8.3.28), планируется полноценная интеграция метаданных активных расширений во внешние отчеты и обработки на уровне Конфигуратора. Конструкторы запросов и СКД смогут работать с добавленными реквизитами напрямую, что существенно упростит жизнь разработчикам и снизит количество подобных ошибок.