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

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

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

Выясняем причину: почему платформа выдает ошибку?

Для начала давайте проанализируем, как платформа «1С:Предприятие» работает с коллекцией параметров табличного документа. Когда мы вызываем метод ПолучитьОбласть(), система считывает указанную секцию макета и динамически создает объект типа ПараметрыОбластиТабличногоДокумента. В эту коллекцию попадают только те имена параметров, которые физически заданы в ячейках данной области макета.

Если в коде мы пишем прямую адресацию к параметру, например:

ОбластьШапка.Параметры.Комм = Коммент;

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

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


Если (СтрНайти(СокрЛП(ПараметрыСеанса.ТекущийПользователь),"Ростов")<>0) или (СтрНайти(СокрЛП(ПараметрыСеанса.ТекущийПользователь),"ИспДир")<>0) Тогда
    Макет = ЭтотОбъект.ПолучитьМакет("Форма1_НаСклад");
Иначе
    Макет = ЭтотОбъект.ПолучитьМакет("Форма1_НаСклад1");
КонецЕсли;

Разработчик добавил параметр Комм в макет Форма1_НаСклад, но забыл продублировать его во второй макет — Форма1_НаСклад1. При тестировании под учетной записью администратора или пользователя из Ростова всё работало прекрасно, но стоило зайти под обычным пользователем, как программа моментально завершала работу с ошибкой.

---

Пошаговый алгоритм диагностики макета

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

  1. Проверьте все используемые макеты. Если в коде предусмотрен выбор макета по условию (как в примере выше), обязательно откройте каждый из них и убедитесь, что новый параметр добавлен во все файлы макетов без исключения.
  2. Проверьте свойства заполнения ячейки. Выделите ячейку в макете, нажмите F4 (или выберите пункт «Свойства» в контекстном меню) и обратите внимание на свойство «Заполнение». Оно должно иметь значение Параметр или Шаблон. Если там установлено значение Текст, то написанное слово воспринимается платформой как статичная строка, и параметр в коллекции создан не будет.
  3. Проверьте синтаксис шаблонов. Если для ячейки выбран тип заполнения Шаблон, то имена параметров внутри нее должны быть обязательно заключены в квадратные скобки. Например: Комментарий: [Комм]. Любые другие скобки (круглые, фигурные) платформа проигнорирует.
  4. Исключите невидимые различия в раскладке клавиатуры. Символы «С» (русская) и «C» (латинская) выглядят абсолютно идентично. Перепишите имя параметра в коде и в свойствах ячейки макета заново, строго в одной раскладке клавиатуры.
  5. Сохраните изменения. Не забывайте сохранять изменения в конфигурации (нажатием клавиши F7) перед запуском отладки. Иногда разработчики просто забывают применить обновленный макет в базу данных.

---

Безопасные методы заполнения параметров печатных форм

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

Решение №1. Использование метода ЗаполнитьЗначенияСвойств()

Метод ЗаполнитьЗначенияСвойств сопоставляет имена свойств источника данных и коллекции параметров макета. Если какого-то параметра в макете не окажется, платформа просто пропустит его заполнение, не вызывая никаких ошибок.

Посмотрим на практический пример реализации:


// Шаг 1. Формируем структуру с данными для заполнения
ДанныеДляПечати = Новый Структура;
ДанныеДляПечати.Вставить("НомерДок", Номер);
ДанныеДляПечати.Вставить("ДатаДок", Дата);
ДанныеДляПечати.Вставить("Дилер", Дилер);
ДанныеДляПечати.Вставить("Город", Дилер.Город);
ДанныеДляПечати.Вставить("Склад", Склад);
ДанныеДляПечати.Вставить("Комм", Коммент);

// Шаг 2. Безопасно заполняем параметры области макета
ЗаполнитьЗначенияСвойств(ОбластьШапка.Параметры, ДанныеДляПечати);

Даже если завтра один из макетов будет изменен пользователем в режиме «1С:Предприятие» и из него удалят поле Комм, этот код продолжит работать стабильно и без сбоев.

Решение №2. Использование метода Параметры.Заполнить()

Если источником данных является сам объект (документ, справочник) или строка выборки запроса, у коллекции параметров области есть встроенный метод Заполнить(). Он работает по аналогичному безопасному принципу сопоставления имен:


// Заполняем область напрямую данными текущего документа
ОбластьШапка.Параметры.Заполнить(ЭтотОбъект);

В этом случае все реквизиты документа, чьи имена совпадают с именами параметров в макете, заполнятся автоматически. Отсутствующие в макете реквизиты никак не повлияют на стабильность выполнения кода.

Решение №3. Программная проверка наличия параметра в области

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

Давайте создадим универсальную вспомогательную функцию для проверки существования параметра в конкретной области макета:


Функция ЕстьПараметрВОбласти(ОбластьМакета, ИмяПараметра) Экспорт
    
    // Создаем уникальный маркер
    Маркер = Новый УникальныйИдентификатор;
    СтруктураПроверки = Новый Структура(ИмяПараметра, Маркер);
    
    // Пытаемся заполнить структуру из параметров макета
    ЗаполнитьЗначенияСвойств(СтруктураПроверки, ОбластьМакета.Параметры);
    
    // Если значение маркера изменилось, значит, параметр существует в макете
    Возврат СтруктураПроверки[ИмяПараметра] <> Маркер;
    
КонецФункции

Теперь мы можем использовать эту функцию в нашем основном коде печати для выборочного и безопасного заполнения:


Если ЕстьПараметрВОбласти(ОбластьШапка, "Комм") Тогда
    // Расчет данных производим только при наличии параметра в макете
    ОбластьШапка.Параметры.Комм = ЭтотОбъект.Комментарий;
КонецЕсли;

---

Анализ смежной проблемы (Сообщение №21)

Во второй части обсуждения пользователь столкнулся со следующей ошибкой в модуле менеджера:

{Документ.бит_стр_РасходныйОрдер.МодульМенеджера(3137)}: Поле объекта не обнаружено (НомерДокумента)

Исходя из полученных знаний, мы сразу можем определить причину неполадки. В документе бит_стр_РасходныйОрдер в области макета с именем Шапка отсутствует параметр НомерДокумента. Либо он был случайно удален в процессе кастомизации макета, либо допущена опечатка в его названии (например, в макете написано НомерДок, а в коде разработчик обращается к НомерДокумента).

Для исправления этой ситуации достаточно либо добавить соответствующий параметр в ячейку области макета, настроив тип заполнения как «Параметр», либо применить безопасное заполнение через функцию ЗаполнитьЗначенияСвойств(), чтобы предотвратить аварийное завершение сеанса пользователя.

Используйте предложенные безопасные методы разработки печатных форм, проверяйте соответствие параметров во всех альтернативных макетах, и ваши решения всегда будут работать стабильно и надежно!

← На главную