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