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

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

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

Почему возникает ошибка «Поле объекта не обнаружено»?

Разберем первопричину проблемы. Когда мы пишем код ВнешниеОбработки.ПоРодителямПраваОбъектов.ПолучитьМакет("Макет"), система 1С ожидает, что в менеджере ВнешниеОбработки существует предопределенный объект с таким именем. Однако, в отличие от справочников или документов, менеджер внешних обработок не хранит в себе коллекцию файлов, находящихся на диске или загруженных в базу через файл-меню. Менеджер ВнешниеОбработки предназначен исключительно для работы с программным интерфейсом: создания (Создать()), подключения (Подключить()) или выбора внешних обработок.

Проанализируем контекст управляемого приложения. В управляемой форме основной реквизит Объект имеет тип ДанныеФормыСтруктура. Этот тип является лишь облегченной «оболочкой» данных и не содержит в себе методов реального прикладного объекта, таких как ПолучитьМакет(). Именно поэтому попытка вызвать получение макета напрямую из реквизита формы или через менеджер приводит к аварийному завершению работы кода.

Решение №1: Использование метода РеквизитФормыВЗначение

Рассмотрим основной и самый правильный способ решения проблемы в контексте управляемой формы. Чтобы получить доступ к методам объекта (включая работу с макетами), нам необходимо временно преобразовать данные формы в полноценный экземпляр объекта ВнешняяОбработкаОбъект.

Для этого в языке 1С предусмотрена системная функция РеквизитФормыВЗначение(). Посмотрим на примере, как должен выглядеть исправленный код процедуры на сервере:


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

Важный нюанс: Метод РеквизитФормыВЗначение работает исключительно на сервере. После получения объекта вы можете использовать любые его экспортные методы и обращаться к макетам. Однако помните, что изменения, внесенные в ОбъектОбработка, не попадут обратно в форму автоматически — для этого потребуется обратный вызов ЗначениеВРеквизитФормы(), но для простого вывода макета в этом нет необходимости. Для отработки подобных серверных вызовов подойдёт шаблон внешней печатной формы со встроенной отладкой из формы.

Решение №2: Программное создание объекта обработки

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

  1. Укажите полный путь к файлу обработки на диске.
  2. Используйте метод ВнешниеОбработки.Создать(ПутьКФайлу, Ложь), где второй параметр отключает безопасный режим (если это требуется для ваших задач).
  3. Получите макет из созданного объекта.

Посмотрим на пример кода:


ПутьКФайлу = "C:\MyReports\MyProcessing.epf";
ОбъектВнешняяОбр = ВнешниеОбработки.Создать(ПутьКФайлу, Ложь);
Макет = ОбъектВнешняяОбр.ПолучитьМакет("ИмяМакета");

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

Решение №3: Вынос логики в модуль объекта

Проанализируем архитектурный подход. Хорошим тоном в разработке на 1С считается вынос логики формирования отчета или обработки данных в Модуль объекта. Это делает код более универсальным и упрощает работу с контекстом. В качестве готового образца такой архитектуры можно использовать пример внешней печатной формы для актуальных версий БСП.

Если вы создадите в модуле объекта экспортную процедуру (например, СформироватьТабДок()), то внутри неё вам не понадобятся никакие преобразования. Вы сможете обращаться к макету напрямую через ключевое слово ЭтотОбъект или просто по имени метода:


// В модуле ОБЪЕКТА
Процедура СформироватьТабДок(ТабДок) Экспорт
    Макет = ПолучитьМакет("Макет"); // Работает напрямую
    // ... логика вывода ...
КонецПроцедуры

// В модуле ФОРМЫ
&НаСервере
Процедура КомандаСформироватьНаСервере()
    ОбъектОбработка = РеквизитФормыВЗначение("Объект");
    ОбъектОбработка.СформироватьТабДок(Результат); // Результат - реквизит формы типа ТабличныйДокумент
КонецПроцедуры

Оптимизация производительности и кэширование

Выясним причину возможных замедлений. При использовании РеквизитФормыВЗначение система создает новый экземпляр объекта в оперативной памяти сервера. Если ваша процедура вызывается очень часто (например, в цикле), это может привести к избыточному потреблению ресурсов.

Рекомендации по оптимизации:

Работа в безопасном режиме

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

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

← На главную