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

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

Как обратиться к макету внешнего отчета в 1С

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

Макет внешнего отчета 1С — это ресурс, встроенный в файл .erf, в котором хранятся табличные шаблоны, схемы компоновки данных, макеты СКД или печатные формы. Обратиться к нему можно несколькими способами, и выбор зависит от того, где выполняется код: внутри самого отчета, из внешней обработки или из конфигурации, подключившей файл программно.

Главная сложность в том, что внешний отчет не входит в состав метаданных конфигурации, поэтому привычный вызов ПолучитьМакет("ИмяМакета") из общего модуля или документа работать не будет. Нужен либо контекст самого отчета, либо объект, созданный через менеджер внешних отчетов.

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

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

Макеты добавляются в конфигураторе на закладке «Макеты» объекта «Внешний отчет». Поддерживаются те же типы, что и у отчетов конфигурации: табличный документ, схема компоновки данных, макет оформления СКД, двоичные данные, текстовый документ и другие.

Важно понимать: макет физически упакован внутрь файла .erf. Если вы открываете отчет через «Файл — Открыть» в режиме предприятия, платформа загружает файл во временное хранилище и работает с ним как с отдельным объектом. Имена макетов чувствительны к регистру только формально — на практике платформа ищет по точному совпадению строки, поэтому лучше копировать имя из свойств макета, а не набирать вручную.

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

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

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

// Модуль объекта внешнего отчета

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

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

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

ОбластьШапка.Параметры.НомерДокумента = "А-001";

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

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

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

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

// Модуль формы внешнего отчета

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

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

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

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

Обращение к макету из внешнего кода

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

// Код вне отчета (например, в модуле внешней обработки)

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

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

Второй параметр метода Создать определяет режим безопасности: Ложь — отчет создается в небезопасном режиме с полными правами, Истина — в безопасном. При работе в файловой базе и с собственными отчетами обычно используют Ложь, но для файлов, полученных извне, безопасный режим обязателен.

Отчет подключен через механизм дополнительных отчетов (БСП)

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

// Требуется подсистема "Дополнительные отчеты и обработки"

СсылкаНаОтчет = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию("Мой отчет");

ОбъектОтчета = ДополнительныеОтчетыИОбработки.ОбъектВнешнейОбработки(СсылкаНаОтчет);

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

Точное имя функции зависит от версии БСП: в одних релизах это ОбъектВнешнейОбработки, в других — ПолучитьОбъектВнешнейОбработки. Сверьтесь с составом общего модуля ДополнительныеОтчетыИОбработки вашей конфигурации.

Порядок действий при обращении извне
  1. 1
    Определите, откуда доступен отчет: файл на диске или справочник дополнительных отчетов
  2. 2
    Создайте объект: ВнешниеОтчеты.Создать(путь) либо через API БСП
  3. 3
    Вызовите у объекта ПолучитьМакет с точным именем макета
  4. 4
    Проверьте тип возвращенного значения — табличный документ, СКД или иной
  5. 5
    Используйте макет: получайте области, заполняйте параметры, выводите в табличный документ

Получение макета СКД и схемы компоновки

Отдельный случай — макет типа «Схема компоновки данных». Внешние отчеты почти всегда строятся на СКД, и основная схема обычно доступна через свойство СхемаКомпоновкиДанных объекта отчета. Но если схем хранится несколько, нужную получают как обычный макет:

// Основная схема отчета

Схема = ОбъектОтчета.СхемаКомпоновкиДанных;

// Дополнительная схема, сохраненная как макет

ДопСхема = ОбъектОтчета.ПолучитьМакет("СхемаДляРуководства");

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

Если отчет открыт интерактивно и нужно подменить схему «на лету», схему помещают во временное хранилище, а адрес присваивают свойству СхемаКомпоновкиДанных настроек отчета. Это типовой прием для отчетов с несколькими вариантами структуры данных.

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

Чаще всего обращение к макету заканчивается ошибкой «Макет не найден». Причины почти всегда одни и те же: опечатка в имени, обращение из контекста, где объект отчета не создан, либо попытка вызвать метод на клиенте в управляемом приложении.

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

Третья группа ошибок связана с правами и безопасным режимом. Если отчет создается в безопасном режиме, а макет содержит, например, ActiveDocument или код, требующий привилегированного режима, часть функциональности будет недоступна. Также в клиент-серверном варианте путь к файлу .erf должен быть доступен именно с сервера, а не с клиентской машины.

Типичные ошибки
01
Опечатка в имени макета — платформа выдает «Макет не найден»; копируйте имя из свойств макета
02
Вызов ПолучитьМакет из модуля формы без РеквизитФормыВЗначение — метод не существует у формы
03
Вызов в клиентском контексте управляемого приложения — перенесите код в серверную процедуру
04
Путь к .erf указан относительно клиента, а код выполняется на сервере — файл не найден
05
Ожидание табличного документа, когда макет имеет тип СКД — несоответствие типов ломает дальнейшую логику

Как проверить, что макет получен корректно

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

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

Если ТипЗнч(Макет) = Тип("ТабличныйДокумент") Тогда

Если Макет.ВысотаТаблицы = 0 Тогда

ВызватьИсключение "Макет получен, но пуст — проверьте содержимое макета в конфигураторе";

КонецЕсли;

КонецЕсли;

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

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

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

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

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

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

Неожиданный тип — вы запросили не тот макет или имя указывает на другой ресурс

Содержимое табличного макета
Норма

ВысотаТаблицы больше нуля, области доступны по именам

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

Пустой документ или ошибка при обращении к области — макет поврежден или устарел

Версия файла .erf
Норма

Изменения, внесенные в конфигураторе, видны при выводе

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

Выводится старый шаблон — в базу загружена прежняя копия файла

Ограничения и безопасная работа

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

Еще одно ограничение — производительность. Каждый вызов ВнешниеОтчеты.Создать с диска читает и распаковывает файл. Если макет нужен многократно в цикле или в регламентном задании, создайте объект один раз и переиспользуйте его, а макет кэшируйте в переменной.

Если отчет используется постоянно, рассмотрите перенос макета в конфигурацию: общий макет доступен из любого места через ПолучитьОбщийМакет, не требует создания объекта отчета и обновляется централизованно вместе с релизом.
ПЗ
Практическое замечание

FAQ

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

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

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

Почти всегда причина в несовпадении имени: лишний пробел, другой регистр или переименование макета без правки кода. Откройте свойства макета в конфигураторе и скопируйте имя оттуда. Реже причина в том, что объект создан из другой версии файла .erf.

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

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

Как обратиться к макету, если отчет хранится в справочнике дополнительных отчетов БСП?

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

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

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

Как получить макет из внешнего отчета в фоновом задании?

В фоновом задании доступен серверный контекст, поэтому схема стандартная: создайте объект через ВнешниеОтчеты.Создать с путем, доступным серверу, и вызовите ПолучитьМакет. Убедитесь, что у пользователя, под которым выполняется задание, есть право на использование внешних отчетов.

Итог

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

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