Разработка и Конфигурация · 9 мин
Как получить макет внешней обработки из формы в 1С
Как получить макет внешней обработки из управляемой и обычной формы в 1С: метод ПолучитьМакет, РеквизитФормыВЗначение, типичные ошибки и примеры кода.
При разработке внешних обработок для 1С часто нужно обратиться к макету — табличному документу, макету СКД или текстовому шаблону, который хранится внутри файла обработки. Загвоздка в том, что из модуля формы привычный вызов ПолучитьМакет("ИмяМакета") не всегда работает так, как ожидается: в управляемых формах контекст объекта обработки отделён от контекста формы, и прямой вызов либо недоступен, либо возвращает ошибку «Метод объекта не обнаружен».
Причина проста: в управляемой форме ЭтотОбъект — это объект типа «УправляемаяФорма», а не объект обработки. Метод ПолучитьМакет() существует у объекта обработки, поэтому сначала нужно получить сам объект — через реквизит формы Объект и функцию РеквизитФормыВЗначение(). В обычных формах всё проще: там ЭтотОбъект уже является объектом обработки, и макет доступен напрямую.
Ниже разобраны рабочие варианты кода для управляемых и обычных форм, способ через общий модуль, типичные ошибки и способы проверить, что макет получен корректно.
Как устроен доступ к макету внешней обработки
Макеты внешней обработки хранятся внутри самого epf-файла и доступны только через объект обработки. В отличие от макетов конфигурации, к ним нельзя обратиться через ПолучитьМакет() из произвольного места кода — нужен экземпляр объекта ВнешняяОбработкаОбъект.
Когда вы открываете форму внешней обработки, платформа создаёт два разных контекста: контекст формы (интерфейс, элементы, реквизиты) и контекст объекта обработки (экспортные процедуры, макеты, табличные части). В обычных формах эти контексты совмещены, в управляемых — разделены, причём объект обработки существует на сервере и на время вызова.
Получение макета в управляемой форме
Основной рабочий приём — преобразовать реквизит формы Объект в прикладной объект и вызвать у него ПолучитьМакет():
&НаСервере
Функция ПолучитьМакетОбработки(ИмяМакета)
ОбъектОбработки = РеквизитФормыВЗначение("Объект");
Возврат ОбъектОбработки.ПолучитьМакет(ИмяМакета);
КонецФункции
Обратите внимание на директиву &НаСервере: РеквизитФормыВЗначение() работает только в серверном контексте. Если вызов идёт из клиентской процедуры (например, из обработчика нажатия кнопки), создайте серверную функцию-обёртку и вызывайте её из клиентского кода.
Пример использования — заполнение табличного документа на форме из макета:
&НаКлиенте
Процедура ПоказатьМакет(Команда)
ПоказатьМакетНаСервере();
КонецПроцедуры
&НаСервере
Процедура ПоказатьМакетНаСервере()
РезультатМакет = РеквизитФормыВЗначение("Объект").ПолучитьМакет("МакетОтчета");
ТабДокумент.Вывести(РезультатМакет);
КонецПроцедуры
- 1Убедитесь, что макет добавлен в дерево макетов внешней обработки и имя указано без опечаток
- 2Создайте серверную процедуру или функцию в модуле формы
- 3Внутри неё вызовите РеквизитФормыВЗначение("Объект").ПолучитьМакет("ИмяМакета")
- 4Обработайте результат по типу макета: табличный документ выводят, СКД передают в компоновщик
- 5Проверьте работу, открыв обработку через Файл — Открыть в режиме 1С:Предприятие
Получение макета в обычной форме
В обычных формах (режим совместимости, толстый клиент) объект обработки доступен через ЭтотОбъект прямо из модуля формы, поэтому код заметно короче:
Процедура КнопкаПечатьНажатие(Элемент)
Макет = ЭтотОбъект.ПолучитьМакет("МакетПечати");
ТабДок = Новый ТабличныйДокумент;
// дальше заполнение областей макета
КонецПроцедуры
Здесь не нужны ни серверные вызовы, ни преобразования реквизитов. Это одна из причин, почему старые обработки, написанные под обычные формы, при переезде на управляемый интерфейс требуют переработки именно в местах обращения к макетам и экспортным методам объекта.
Альтернативные способы и когда их применять
Если обращений к макету много, удобнее вынести логику в модуль объекта обработки: создать там экспортную функцию ПолучитьМакетОбработки(ИмяМакета) и вызывать её из формы через тот же РеквизитФормыВЗначение("Объект"). Так весь код работы с макетами остаётся в одном месте, а форма отвечает только за отображение.
Другой вариант — получить макет вообще без формы, например из фонового задания или внешнего соединения. Для этого объект обработки создают явно через ВнешниеОбработки.Создать(ПутьКФайлу), после чего макет доступен стандартным методом. Этот способ подходит для регламентных операций, где форма не открывается.
Сравнение вариантов
Стандартный способ для управляемой формы. Требует серверного контекста, на каждый вызов создаёт объект заново
Только обычные формы. Самый короткий код, но не работает в управляемом интерфейсе
Удобно при множественных обращениях и для переиспользования логики; требует доработки модуля объекта
Для работы без формы: фоновые задания, COM-соединения. Нужен путь к файлу или регистрация в справочнике дополнительных обработок
Типичные ошибки и как их исправить
Самая частая ошибка — «Метод объекта не обнаружен (ПолучитьМакет)». Она возникает, когда в управляемой форме пытаются вызвать ЭтаФорма.ПолучитьМакет() или Объект.ПолучитьМакет() напрямую: реквизит формы Объект — это данные формы, а не прикладной объект, и методов объекта у него нет.
Вторая распространённая проблема — «Макет не найден». Проверьте, что макет добавлен именно в макеты внешней обработки (а не формы), имя в коде совпадает с именем в дереве метаданных с точностью до символа, и файл обработки сохранён после добавления макета.
Третья группа ошибок связана с контекстом: вызов РеквизитФормыВЗначение() на клиенте приводит к ошибке компиляции или выполнения. Признак — сообщение о недоступности метода в данном контексте. Решение — перенести вызов в серверную процедуру.
Как проверить результат
После внедрения кода откройте обработку в режиме 1С:Предприятие через «Файл → Открыть» и выполните действие, которое запрашивает макет. Если макет — табличный документ, убедитесь, что он вывелся в поле формы или открылся для предпросмотра. Если макет — схема компоновки, проверьте, что отчёт формируется без ошибок компоновщика.
Для отладки полезно временно вывести тип полученного значения: Сообщить(ТипЗнч(Макет)). Для табличного макета вы увидите «Табличный документ», для СКД — «Схема компоновки данных». Если возвращается Неопределено или падает ошибка — проблема в имени макета или в контексте вызова.
Как проверить результат
Метод возвращает значение ожидаемого типа без исключений
Ошибка «Метод объекта не обнаружен» или «Макет не найден»
ТабличныйДокумент для печатных форм, СхемаКомпоновкиДанных для СКД
Неопределено или тип, не соответствующий назначению макета
Макет выводится в форму или отчёт строится корректно
Пустая область вывода или ошибка компоновки
Частые вопросы
Можно ли получить макет внешней обработки без открытия формы?
Да. Создайте объект обработки через ВнешниеОбработки.Создать(ПолноеИмяФайла) и вызовите у него ПолучитьМакет(). Если обработка зарегистрирована в справочнике дополнительных отчётов и обработок, объект создаётся через методы соответствующего общего модуля БСП.
Почему РеквизитФормыВЗначение("Объект") возвращает ошибку на клиенте?
Этот метод существует только в серверном контексте управляемой формы. Вынесите обращение в процедуру с директивой &НаСервере и вызывайте её из клиентского обработчика.
Как получить макет СКД из внешнего отчёта?
Точно так же: РеквизитФормыВЗначение("Объект").ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных"). Для внешних отчётов (erf) механизм идентичен обработкам.
Макет лежит в макетах формы, но ПолучитьМакет его не видит. Почему?
Метод ПолучитьМакет() объекта обработки ищет только среди макетов самой обработки. Макеты формы доступны через свойство формы Макеты либо их стоит перенести на уровень обработки, если они нужны объекту.
Можно ли кэшировать макет, чтобы не вызывать ПолучитьМакет каждый раз?
Можно: сохраните полученный табличный документ в реквизит формы подходящего типа при первом обращении и дальше используйте его. Учтите, что сам объект обработки между серверными вызовами не живёт — кэшировать имеет смысл только результат, а не объект.
Что важно запомнить
Макет внешней обработки принадлежит объекту, а не форме. В управляемой форме получайте его через РеквизитФормыВЗначение("Объект").ПолучитьМакет() в серверном контексте, в обычной — через ЭтотОбъект.ПолучитьМакет(). Ошибки чаще всего связаны с контекстом вызова и неверным именем макета.