Приветствуем вас, уважаемые разработчики! При создании или доработке печатных форм в системе «1С:Предприятие» одной из самых распространенных и досадных ошибок является исключение «Поле объекта не обнаружено», указывающее на имя какого-либо параметра макета. Давайте вместе подробно разберем, почему возникает эта ошибка, как быстро найти ее причину и как писать код так, чтобы полностью исключить подобные падения системы в будущем.
Для начала давайте проанализируем, как платформа «1С:Предприятие» работает с коллекцией параметров табличного документа. Когда мы вызываем метод ПолучитьОбласть(), система считывает указанную секцию макета и динамически создает объект типа ПараметрыОбластиТабличногоДокумента. В эту коллекцию попадают только те имена параметров, которые физически заданы в ячейках данной области макета.
Если в коде мы пишем прямую адресацию к параметру, например:
ОбластьШапка.Параметры.Комм = Коммент;
а в самом макете ячейка с параметром Комм отсутствует, платформа не сможет найти такое свойство у динамического объекта Параметры. В результате выполнение программного кода прерывается критической ошибкой: «Поле объекта не обнаружено (Комм)».
В ситуации, с которой столкнулся автор темы, проблема усугублялась наличием ветвления в коде. В зависимости от текущего пользователя система выбирала один из двух разных макетов:
Если (СтрНайти(СокрЛП(ПараметрыСеанса.ТекущийПользователь),"Ростов")<>0) или (СтрНайти(СокрЛП(ПараметрыСеанса.ТекущийПользователь),"ИспДир")<>0) Тогда
Макет = ЭтотОбъект.ПолучитьМакет("Форма1_НаСклад");
Иначе
Макет = ЭтотОбъект.ПолучитьМакет("Форма1_НаСклад1");
КонецЕсли;
Разработчик добавил параметр Комм в макет Форма1_НаСклад, но забыл продублировать его во второй макет — Форма1_НаСклад1. При тестировании под учетной записью администратора или пользователя из Ростова всё работало прекрасно, но стоило зайти под обычным пользователем, как программа моментально завершала работу с ошибкой.
---
Если вы столкнулись с подобной ошибкой, давайте разберем по шагам, что необходимо проверить в конфигураторе:
Комментарий: [Комм]. Любые другие скобки (круглые, фигурные) платформа проигнорирует.---
Чтобы навсегда обезопасить свой код от падений при редактировании макетов пользователями или при создании сложных печатных форм с множеством условий, рекомендуется отказаться от прямого присвоения значений параметрам. Давайте рассмотрим более надежные и профессиональные подходы.
Метод ЗаполнитьЗначенияСвойств сопоставляет имена свойств источника данных и коллекции параметров макета. Если какого-то параметра в макете не окажется, платформа просто пропустит его заполнение, не вызывая никаких ошибок.
Посмотрим на практический пример реализации:
// Шаг 1. Формируем структуру с данными для заполнения
ДанныеДляПечати = Новый Структура;
ДанныеДляПечати.Вставить("НомерДок", Номер);
ДанныеДляПечати.Вставить("ДатаДок", Дата);
ДанныеДляПечати.Вставить("Дилер", Дилер);
ДанныеДляПечати.Вставить("Город", Дилер.Город);
ДанныеДляПечати.Вставить("Склад", Склад);
ДанныеДляПечати.Вставить("Комм", Коммент);
// Шаг 2. Безопасно заполняем параметры области макета
ЗаполнитьЗначенияСвойств(ОбластьШапка.Параметры, ДанныеДляПечати);
Даже если завтра один из макетов будет изменен пользователем в режиме «1С:Предприятие» и из него удалят поле Комм, этот код продолжит работать стабильно и без сбоев.
Если источником данных является сам объект (документ, справочник) или строка выборки запроса, у коллекции параметров области есть встроенный метод Заполнить(). Он работает по аналогичному безопасному принципу сопоставления имен:
// Заполняем область напрямую данными текущего документа
ОбластьШапка.Параметры.Заполнить(ЭтотОбъект);
В этом случае все реквизиты документа, чьи имена совпадают с именами параметров в макете, заполнятся автоматически. Отсутствующие в макете реквизиты никак не повлияют на стабильность выполнения кода.
Бывают ситуации, когда перед заполнением параметра нужно выполнить сложные расчеты, которые не хочется запускать вхолостую, если параметра в макете нет. К сожалению, стандартная коллекция Параметры у табличного документа не поддерживает метод Свойство().
Давайте создадим универсальную вспомогательную функцию для проверки существования параметра в конкретной области макета:
Функция ЕстьПараметрВОбласти(ОбластьМакета, ИмяПараметра) Экспорт
// Создаем уникальный маркер
Маркер = Новый УникальныйИдентификатор;
СтруктураПроверки = Новый Структура(ИмяПараметра, Маркер);
// Пытаемся заполнить структуру из параметров макета
ЗаполнитьЗначенияСвойств(СтруктураПроверки, ОбластьМакета.Параметры);
// Если значение маркера изменилось, значит, параметр существует в макете
Возврат СтруктураПроверки[ИмяПараметра] <> Маркер;
КонецФункции
Теперь мы можем использовать эту функцию в нашем основном коде печати для выборочного и безопасного заполнения:
Если ЕстьПараметрВОбласти(ОбластьШапка, "Комм") Тогда
// Расчет данных производим только при наличии параметра в макете
ОбластьШапка.Параметры.Комм = ЭтотОбъект.Комментарий;
КонецЕсли;
---
Во второй части обсуждения пользователь столкнулся со следующей ошибкой в модуле менеджера:
{Документ.бит_стр_РасходныйОрдер.МодульМенеджера(3137)}: Поле объекта не обнаружено (НомерДокумента)
Исходя из полученных знаний, мы сразу можем определить причину неполадки. В документе бит_стр_РасходныйОрдер в области макета с именем Шапка отсутствует параметр НомерДокумента. Либо он был случайно удален в процессе кастомизации макета, либо допущена опечатка в его названии (например, в макете написано НомерДок, а в коде разработчик обращается к НомерДокумента).
Для исправления этой ситуации достаточно либо добавить соответствующий параметр в ячейку области макета, настроив тип заполнения как «Параметр», либо применить безопасное заполнение через функцию ЗаполнитьЗначенияСвойств(), чтобы предотвратить аварийное завершение сеанса пользователя.
Используйте предложенные безопасные методы разработки печатных форм, проверяйте соответствие параметров во всех альтернативных макетах, и ваши решения всегда будут работать стабильно и надежно!