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

Отчеты и Аналитика · 11 мин

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

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

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

Задача получения макета возникает в нескольких ситуациях: при выводе печатной формы в табличный документ, при построении отчета на СКД с собственным макетом компоновки, при чтении шаблона файла (например, Excel или Word) из двоичных данных. В каждом случае синтаксис немного отличается, и ошибка в способе обращения — самая частая причина сообщения «Макет не найден».

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

Где хранится макет во внешнем отчете и как его добавить

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

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

Важный нюанс: макет сохраняется внутри файла .erf. Если вы обновили макет в конфигураторе, но в базе используется старая версия файла, подключенная через справочник дополнительных отчетов и обработок, изменения не подхватятся. Нужно обновить файл в справочнике или перезаписать его в каталоге, откуда он загружается.

Получение макета из модуля объекта отчета

Самый простой и надежный способ — обращение к макету из модуля объекта самого отчета. Здесь доступен контекст ЭтотОбъект, и вызов выглядит так:

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

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

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

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

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

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

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

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

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

Получение макета из модуля формы внешнего отчета

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

Типовой прием для управляемой формы выглядит так:

&НаСервере

Функция ПолучитьТабличныйМакет()

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

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

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

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

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

Получение макета из внешнего кода через менеджер внешних отчетов

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

ОтчетОбъект = ВнешниеОтчеты.Создать("C:\Отчеты\МойОтчет.erf");

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

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

Этот способ требует права на использование внешних отчетов у текущего пользователя. В файловой базе с отключенной защитой от опасных действий код выполнится без вопросов; в клиент-серверном варианте или при включенных профилях безопасности создание внешнего отчета может быть заблокировано администратором.

Особые случаи: СКД, двоичные данные и макеты оформления

Макет схемы компоновки данных

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

Макет с двоичными данными (шаблон Excel, Word)

Для макетов типа «Двоичные данные» метод вернет объект ДвоичныеДанные. Его сохраняют во временный файл и открывают прикладным механизмом — например, через COM-объект Excel или через табличный документ, если это шаблон MXL. Не забудьте удалить временный файл после использования, особенно в серверном коде: накопление файлов во временном каталоге сервера — реальная проблема долгоживущих баз.

Макет ActiveDocument и HTML

Макеты типа HTML-документ и текстовый документ возвращают соответствующие объекты платформы. Их удобно использовать для шаблонов писем и произвольных печатных форм с подстановкой параметров через СтрЗаменить() или поиск плейсхолдеров.

Сравнение способов получения макета

ЭтотОбъект.ПолучитьМакет() в модуле объекта

Самый простой и надежный вариант; работает только внутри кода самого отчета

РеквизитФормыВЗначение("Отчет") в управляемой форме

Стандартный путь для форм; требует серверного контекста и аккуратной передачи результата на клиента

ВнешниеОтчеты.Создать() из внешнего кода

Подходит для обработок и интеграций; требует прав и доверия к файлу отчета

Проверка результата и типичные ошибки

После получения макета убедитесь, что вернулся объект ожидаемого типа. Быстрая проверка в отладчике или через ТипЗнч() избавит от ошибок на этапе обращения к областям: если вместо табличного документа вернулись двоичные данные, вызов ПолучитьОбласть() завершится исключением.

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

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

Тип возвращенного объекта
Норма

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

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

Неопределено или объект другого типа — имя макета неверно или макет не сохранен в файле

Наличие областей в табличном макете
Норма

ПолучитьОбласть("Шапка") возвращает область без исключения

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

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

Актуальность файла отчета в базе
Норма

Изменения макета видны после обновления файла в справочнике дополнительных отчетов

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

Используется старая версия макета — файл в базе не обновлен

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

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

Держите имена макетов и областей в строковых константах или перечислении-подобной структуре в начале модуля. Когда макетов становится больше трех-четырех, это заметно упрощает рефакторинг и поиск всех мест использования конкретного макета.
ПЗ
Практическое замечание

FAQ

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

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

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

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

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

Аналогично, но через менеджер ВнешниеОбработки: ВнешниеОбработки.Создать("ПутьКФайлу.epf").ПолучитьМакет("ИмяМакета"). Внутри модуля объекта обработки работает тот же ЭтотОбъект.ПолучитьМакет().

Можно ли изменить макет программно без конфигуратора?

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

Работает ли ПолучитьМакет() в безопасном режиме?

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

Как узнать, какие макеты есть внутри файла .erf, не открывая конфигуратор?

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

Итог

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

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