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