К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как получить макет во внешней обработке 1С

Как получить макет во внешней обработке 1С: методы ПолучитьМакет и ПолучитьОбщийМакет, добавление макета в обработку, типовые ошибки и их решение.

Макет во внешней обработке 1С нужен для печатных форм, табличных документов, схем компоновки данных и других шаблонов. Главное отличие от работы внутри конфигурации — внешняя обработка не имеет доступа к общим макетам напрямую через свои собственные макеты тем же способом, и разработчики часто сталкиваются с ошибкой «Макет не найден».

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

Ниже разобраны все рабочие сценарии с примерами кода для управляемых и обычных форм, типичные ошибки и способы их диагностики.

Добавление макета во внешнюю обработку

Прежде чем получать макет кодом, его нужно физически добавить в обработку. Откройте внешнюю обработку в конфигураторе, в дереве объекта найдите ветку «Макеты», нажмите правой кнопкой и выберите «Добавить». Конструктор предложит тип макета: табличный документ, текстовый документ, схема компоновки данных, двоичные данные и другие.

Для печатных форм почти всегда используется тип «Табличный документ». Внутри макета создаются именованные области — «Шапка», «Строка», «Подвал» и т.д. Именно по именам областей вы потом будете выводить секции в результирующий документ.

Имя макета задайте осмысленное и без пробелов — например, МакетПечати или ПФ_MXL_СчетНаОплату. Имя чувствительно к точному написанию: код ПолучитьМакет("макетпечати") не найдёт макет с именем «МакетПечати» в строгом смысле регистронезависимости 1С здесь нет при поиске по строковому имени — на практике поиск регистронезависим, но опечатки в символах критичны.

Получение макета из самой обработки

Основной сценарий — макет хранится внутри внешней обработки. В модуле объекта обработки (или в модуле формы с доступом к объекту) вызовите метод ПолучитьМакет():

// В модуле объекта обработки

Функция ПечатьДокумента(СсылкаНаДокумент) Экспорт

ТабДок = Новый ТабличныйДокумент;

Макет = ПолучитьМакет("МакетПечати");

ОбластьШапка = Макет.ПолучитьОбласть("Шапка");

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

ТабДок.Вывести(ОбластьШапка);

Возврат ТабДок;

КонецФункции

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

// В модуле управляемой формы

&НаСервере

Функция ПолучитьМакетОбработки()

ОбработкаОбъект = РеквизитФормыВЗначение("Объект");

Возврат ОбработкаОбъект.ПолучитьМакет("МакетПечати");

КонецФункции

Для обычных форм (толстый клиент) доступ проще — ЭтотОбъект.ПолучитьМакет("МакетПечати") работает напрямую из модуля формы, если обработка открыта как объект.

Получение макета из внешнего файла

Третий сценарий — макет лежит отдельным файлом (MXL, шаблон Word и т.п.). Табличный документ можно загрузить из файла напрямую:

ТабДок = Новый ТабличныйДокумент;

ТабДок.Прочитать("C:\Шаблоны\Макет.mxl");

Для файлов в формате двоичных данных, хранящихся в справочнике или регистре, используйте временный файл: запишите двоичные данные во временный файл, прочитайте его табличным документом, затем удалите временный файл. Это типовой приём для шаблонов, которые пользователи редактируют самостоятельно.

Главный риск этого подхода — отсутствие файла по указанному пути на сервере. Метод Прочитать() выполняется в том контексте, где запущен код: если код серверный, путь ищется на сервере, а не на компьютере пользователя. Всегда проверяйте существование файла и обрабатывайте исключения.

Работа с макетом в механизме «Дополнительные отчеты и обработки»

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

Функция Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати) Экспорт

Макет = ПолучитьМакет("ПФ_MXL_Счет");

// ... формирование табличного документа

КонецФункции

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

Удобно проверять наличие макета ещё до формирования печати: откройте обработку в конфигураторе и в дереве метаданных убедитесь, что макет виден. Если макет добавляли копированием из другой обработки, проверьте, что скопировался сам макет, а не только ссылка на него.
ПЗ
Практическое замечание

Типичные ошибки и их диагностика

Самая распространённая ошибка — «Макет не найден». Причины почти всегда одни и те же: макет не добавлен в обработку, имя указано с опечаткой, либо вызывается ПолучитьОбщийМакет() вместо ПолучитьМакет() (и наоборот). Проверьте имя посимвольно, включая регистр букв в сложных именах с подчёркиваниями.

Вторая частая проблема — ошибка «Метод объекта не обнаружен (ПолучитьМакет)» при вызове из модуля формы. Это значит, что код выполняется в контексте формы, где такого метода нет. Решение — получить объект обработки через РеквизитФормыВЗначение("Объект") и вызвать метод у него.

Третья ситуация — макет получен, но области не выводятся. Здесь проверяйте имена областей в макете: область «Шапка» и «шапка» в коде обычно совместимы по регистру, но лишний пробел или другое слово приведут к ошибке «Область не найдена». Откройте макет и сверьте имена областей в левой панели редактора.

Типичные ошибки
01
Вызов ПолучитьМакет() из модуля формы — метод есть только у объекта обработки, форма его не имеет
02
Опечатка в имени макета или области — ошибка «Макет не найден» без подсказки, где искать
03
Использование ПолучитьОбщийМакет() для макета, хранящегося в обработке, — общие макеты ищутся только в конфигурации
04
Забыли сохранить и переоткрыть обработку после добавления макета — в сеансе работает старая версия файла
05
Серверный код читает макет с локального диска клиента — файл физически недоступен на сервере

Проверка результата

После внедрения кода проверьте цепочку целиком: обработка открывается в базе, макет получается без исключения, области выводятся в табличный документ, параметры заполняются данными. Быстрый способ отладки — временно вывести полученный макет на экран: Макет.Показать() в толстом клиенте или вывести область в табличный документ и открыть его.

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

Контрольные точки

Как проверить результат

Вызов ПолучитьМакет()
Норма

Возвращается объект макета, исключения нет

Тревожный признак

Ошибка «Макет не найден» — проверить имя и наличие макета в обработке

Получение области
Норма

Макет.ПолучитьОбласть() возвращает область с заполненными параметрами

Тревожный признак

Ошибка «Область не найдена» — сверить имя области в редакторе макета

Итоговый табличный документ
Норма

Документ содержит все секции с данными

Тревожный признак

Пустой документ или пропущенные секции — проверить цикл вывода и условия

Итог

Что важно запомнить

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

Частые вопросы

Почему возникает ошибка «Макет не найден», хотя макет добавлен?

Чаще всего обработка в сеансе не переоткрыта после добавления макета — в памяти старая версия файла. Закройте и заново откройте обработку. Если не помогло, сверьте имя макета в конфигураторе с именем в коде посимвольно.

Можно ли получить макет на клиенте в управляемом приложении?

Нет, ПолучитьМакет() и ПолучитьОбщийМакет() выполняются только на сервере. В управляемой форме создайте серверную функцию, получите в ней макет или готовый табличный документ и верните результат на клиент.

Как получить макет, если код написан в модуле формы?

У формы нет метода ПолучитьМакет(). Получите объект обработки вызовом РеквизитФормыВЗначение("Объект") и вызовите ПолучитьМакет() у полученного объекта. В обычных формах толстого клиента доступен ЭтотОбъект.ПолучитьМакет().

Чем отличается ПолучитьМакет от ПолучитьОбщийМакет?

ПолучитьМакет() ищет макет внутри самой обработки, ПолучитьОбщийМакет() — среди общих макетов конфигурации. Для автономной внешней обработки правильный выбор — первый вариант, чтобы не зависеть от состава конфигурации.

Как хранить макет, который пользователи должны редактировать сами?

Храните шаблон в базе данных — в справочнике или регистре сведений как двоичные данные. При формировании печати выгружайте данные во временный файл и читайте его табличным документом. Так пользователи меняют шаблон без изменения кода обработки.

Почему печатная форма выводится пустой без ошибок?

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