Как в управляемой форме 1С динамически получить макет отчета без обращения по имени

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке отчетов и обработок в платформе 1С:Предприятие часто возникает задача обращения к макету (табличному документу или схеме компоновки данных) напрямую из кода. Жесткая привязка вида Отчеты.МойОтчет.ПолучитьМакет("Макет") имеет существенный недостаток: при тиражировании кода или переименовании отчета приходится вручную править имя объекта в каждом месте вызова. Разберем, как избавиться от жесткого кодирования и универсально получать макет отчета из кода формы или модуля объекта.

Почему возникает сложность в управляемом приложении

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

Рассмотрим основные способы динамического обращения к макету в зависимости от контекста выполнения кода.

Способ 1. Получение макета в модуле управляемой формы через преобразование реквизита

Проанализируем ситуацию, когда код выполняется в серверном контексте модуля формы отчета. Чтобы обратиться к методам самого прикладного объекта (отчета), нам необходимо преобразовать данные формы в контекст объекта с помощью функции РеквизитФормыВЗначение().

Посмотрим на пример реализации данного подхода:


&НаСервере
Функция ПолучитьМакетОтчетаНаСервере(ИмяМакета)
    
    // Преобразуем реквизит формы "Объект" (или "Отчет") в объект отчета
    ОтчетОбъект = РеквизитФормыВЗначение("Объект");
    
    // Получаем нужный макет напрямую из объекта
    Макет = ОтчетОбъект.ПолучитьМакет(ИмяМакета);
    
    Возврат Макет;
    
КонецФункции

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

Данный метод универсален: он отлично работает как для отчетов из дерева метаданных конфигурации, так и для внешних отчетов (файлов .erf) и отчетов из расширений.

Способ 2. Динамическое обращение через метаданные объекта

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


&НаСервере
Функция ПолучитьМакетЧерезМенеджер(ИмяМакета)
    
    ОтчетОбъект = РеквизитФормыВЗначение("Объект");
    ИмяОтчета = ОтчетОбъект.Метаданные().Имя;
    
    // Обращаемся к менеджеру отчета через коллекцию
    Макет = Отчеты[ИмяОтчета].ПолучитьМакет(ИмяМакета);
    
    Возврат Макет;
    
КонецФункции

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

Способ 3. Получение макета в модуле объекта отчета

Если логика формирования или обработки макета находится внутри модуля объекта отчета (а не в модуле формы), то обращение выполняется еще проще. В контексте модуля объекта доступен сам экземпляр, поэтому вызывать дополнительные методы преобразования не требуется.

Разберем пример кода в модуле объекта:


Процедура ОбработатьДанные()
    
    // Прямое обращение к текущему экземпляру отчета
    Макет = ЭтотОбъект.ПолучитьМакет("МойМакет");
    
    // Или сокращенная запись
    // Макет = ПолучитьМакет("МойМакет");
    
КонецПроцедуры

Важные правила и ограничения

  1. Метод РеквизитФормыВЗначение() доступен **только на сервере** в контекстных процедурах (с директивой &НаСервере). В процедурах &НаСервереБезКонтекста и на клиенте &НаКлиенте данный метод вызвать нельзя.
  2. Получение макета всегда требует серверного вызова. Если макет нужен на клиенте (например, для выгрузки или показа), выполните вызов серверной функции, которая вернет готовый табличный документ или данные макета.
  3. Для внешних отчетов единственный надежный способ получить макет без ошибки — получение через экземпляр объекта (РеквизитФормыВЗначение в форме или ЭтотОбъект в модуле).
← На главную