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