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

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

Как получить макет из общих макетов в 1С

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

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

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

Ниже разобраны оба подхода, типы возвращаемых значений, особенности клиент-серверного вызова и типичные ошибки, с которыми сталкиваются разработчики при работе с общими макетами.

Способ 1: ПолучитьОбщийМакет() — прямое обращение к общему макету

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

Макет = ПолучитьОбщийМакет("МакетПечатиЗаказа");

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

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

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

Если макет с указанным именем не существует, платформа вызовет исключение с сообщением об ошибке. Имя чувствительно к точности написания, но не к регистру: «МакетПечати» и «МАКЕТПЕЧАТИ» будут восприняты одинаково.

Способ 2: ПолучитьМакет() через менеджер объекта

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

// Макет самого объекта

МакетОбъекта = Справочники.Номенклатура.ПолучитьМакет("КарточкаТовара");

// Общий макет через менеджер объекта

МакетОбщий = Справочники.Номенклатура.ПолучитьМакет("ОбщийМакет.МакетПечатиЗаказа");

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

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

Что возвращает метод: типы макетов и их обработка

Тип возвращаемого значения определяется видом макета, заданным при его создании в конфигураторе. От этого зависит, какие операции доступны дальше.

Вид макетаВозвращаемый типТипичное применение
Табличный документТабличныйДокументПечатные формы, макеты областей
Схема компоновки данныхСхемаКомпоновкиДанныхОтчёты на СКД, динамические списки
Двоичные данныеДвоичныеДанныеКартинки, внешние компоненты, файлы
Текстовый документТекстовыйДокументШаблоны текста, скрипты, запросы
HTML-документСтрока / ТекстовыйДокументОтображение в поле HTML
Географическая схема, графическая схемаСоответствующий типСхемы, карты, бизнес-процессы

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

// Пример: двоичные данные из общего макета

ДвоичныеДанные = ПолучитьОбщийМакет("ВнешняяКомпонентаПечати");

АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификаторФормы);

Получение макета в управляемой форме: клиент и сервер

В управляемых формах код разделён на клиентскую и серверную части. Получение макета и формирование табличного документа — ресурсоёмкие операции, которые правильно выполнять на сервере. Клиенту передаётся уже готовый результат.

&НаКлиенте

Процедура Печать(Команда)

ТабДок = СформироватьПечатнуюФормуНаСервере();

ТабДок.Показать("Печатная форма");

КонецПроцедуры

&НаСервере

Функция СформироватьПечатнуюФормуНаСервере()

Макет = ПолучитьОбщийМакет("МакетПечатиЗаказа");

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

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

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

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

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

Обратите внимание: табличный документ можно вернуть с сервера на клиент напрямую, а вот сам «сырой» макет некоторых типов сериализовать нельзя. Поэтому паттерн «получить макет на сервере, обработать там же, вернуть результат» — стандартный подход.

Типичные ошибки и их причины

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

Вторая частая проблема — попытка получить макет объекта через ПолучитьОбщийМакет() или наоборот. Если макет лежит внутри документа «РеализацияТоваровУслуг», то ПолучитьОбщийМакет("МакетРеализации") завершится ошибкой — нужен вызов Документы.РеализацияТоваровУслуг.ПолучитьМакет("МакетРеализации").

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

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

Общие макеты и макеты объектов: что выбрать

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

Макет внутри объекта оправдан, когда он логически принадлежит только этому объекту: печатная форма конкретного документа, схема компоновки конкретного отчёта. Тогда макет находится рядом с использующим его кодом, и при копировании объекта макет копируется вместе с ним.

Сравнение вариантов

Общий макет

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

Макет объекта

Подходит для шаблона одного объекта. Ограничение: дублирование, если тот же шаблон нужен другим объектам.

Макет во внешней обработке

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

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

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

Макет = ПолучитьОбщийМакет("МакетПечатиЗаказа");

Макет.Показать("Проверка макета");

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

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

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

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

Вызов ПолучитьОбщийМакет
Норма

Метод возвращает объект без исключения

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

Исключение «Макет не найден» — проверьте имя и наличие макета в конфигураторе

Тип возвращённого значения
Норма

Соответствует типу макета (ТабличныйДокумент, СхемаКомпоновкиДанных и т.д.)

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

Тип другой — проверьте свойство «Тип макета»

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

Область получена и выводится в табличный документ

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

Исключение при ПолучитьОбласть — имени области нет в макете

Контекст выполнения
Норма

Код работает в серверной процедуре

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

Ошибка вызова на клиенте — перенесите получение макета на сервер

Часто задаваемые вопросы

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

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

Можно ли получить общий макет на тонком клиенте?

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

Как получить макет внешней обработки или внешнего отчёта?

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

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

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

Как передать макет или данные из него в управляемую форму?

Непосредственно макет передавать не нужно. Сформируйте на сервере табличный документ и верните его клиенту — он сериализуется без проблем. Двоичные данные из макета поместите во временное хранилище через ПоместитьВоВременноеХранилище() и передайте на клиент адрес хранилища.

Можно ли изменить общий макет программно и сохранить его?

Нет. Полученный макет — это копия для чтения и вывода данных: можно заполнять параметры областей, менять ячейки в полученном табличном документе, но сохранить изменения обратно в конфигурацию программно нельзя. Изменение самого макета выполняется только в конфигураторе.

Итог

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

Общий макет получают вызовом ПолучитьОбщийМакет("ИмяМакета"); тип результата зависит от вида макета. В управляемых формах получайте и обрабатывайте макет на сервере. Большинство ошибок связано с опечатками в имени, неправильным выбором метода и нарушением клиент-серверного контекста.