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

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

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

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

Если программный код выполняется непосредственно в модуле объекта внешней обработки, процедура получения макета максимально проста. В этом контексте методы обработки доступны напрямую. Рассмотрим простейший пример:


// Находимся в модуле объекта обработки
Макет = ПолучитьМакет("ИмяВашегоМакета");
// Далее работаем с макетом, например, получаем область
Область = Макет.ПолучитьОбласть("Заголовок");

Этот способ работает безотказно, так как контекст модуля объекта «знает» о существовании своих метаданных, включая макеты. Однако часто задача усложняется тем, что команду на формирование отчета или печатной формы инициирует пользователь, нажимая кнопку на форме.

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

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

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

  1. Создаем процедуру с директивой &НаСервере.
  2. Используем функцию РеквизитФормыВЗначение(), чтобы получить полноценный объект обработки из данных формы.
  3. Вызываем метод ПолучитьМакет() у полученного объекта.

Проанализируем пример кода для внешней обработки:


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

Важное примечание: Если вы разрабатываете внешний отчет, то в функцию РеквизитФормыВЗначение необходимо передавать строку "Отчет", а не "Объект". Это связано с тем, что в стандартных управляемых формах отчетов основной реквизит называется именно так. Ошибка в имени параметра приведет к исключению «Недопустимое значение параметра».

Способ 3. Перенос логики в модуль объекта (идеологически верный)

Рассмотрим ситуацию, когда функционал формирования отчета становится объемным. Опытные разработчики рекомендуют не загромождать модуль формы серверными вызовами, а переносить всю бизнес-логику в модуль объекта. Это делает код более универсальным — вы сможете вызвать функцию печати и из формы, и программно из другого места системы.

Разберем, как это реализовать по шагам:

Шаг 1. В модуле объекта создаем экспортную функцию:


Функция СформироватьПечатнуюФорму() Экспорт
    Макет = ПолучитьМакет("Макет1");
    ТабДок = Новый ТабличныйДокумент;
    
    // ... здесь ваш код формирования (запросы, заполнение параметров) ...
    
    Возврат ТабДок;
КонецФункции

Шаг 2. В модуле формы вызываем эту функцию:


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

&НаКлиенте
Процедура Сформировать(Команда)
    РезультатТабДок = СформироватьНаСервере();
    РезультатТабДок.Показать("Печать отчета");
КонецПроцедуры

Особенности работы с СКД и внешними файлами

Если ваша внешняя обработка использует Схему компоновки данных (СКД), то получить её можно аналогичным способом. Метод ПолучитьМакет() вернет объект типа СхемаКомпоновкиДанных, если в метаданных этот макет указан как СКД.

Также стоит помнить о производительности. При использовании РеквизитФормыВЗначение() система фактически создает экземпляр объекта в памяти сервера. Если процедура формирования вызывается очень часто, рассмотрите возможность кэширования макета или использования серверных модулей, если это позволяют условия задачи.

Посмотрим на практический пример запроса и вывода данных в макет, который часто применяется во внешних отчетах по остаткам:


&НаСервере
Процедура ВыполнитьПостроениеОтчета(ТабДок)
    // Получаем макет через преобразование реквизита
    Макет = РеквизитФормыВЗначение("Объект").ПолучитьМакет("Макет");
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Товары.Номенклатура,
        |   Товары.КоличествоОстаток
        |ИЗ
        |   РегистрНакопления.ТоварыНаСкладах.Остатки КАК Товары";
    
    Результат = Запрос.Выполнить();
    Выборка = Результат.Выбрать();
    
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    
    Пока Выборка.Следующий() Цикл
        ОбластьСтрока.Параметры.Заполнить(Выборка);
        ТабДок.Вывести(ОбластьСтрока);
    КонецЦикла;
КонецПроцедуры

Подводя итог, можно сказать: для успешного получения макета всегда проверяйте контекст выполнения кода и тип метаданных (Обработка или Отчет), с которым вы работаете. Использование РеквизитФормыВЗначение() является «золотым стандартом» при работе в управляемом интерфейсе 1С 8.3.

← На главную