Как получить макет внешней обработки в управляемых формах 1С?

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

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

Причина возникновения проблемы

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

Базовый метод: Использование функции РеквизитФормыВЗначение

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

Во-первых, создадим на сервере функцию, которая будет возвращать макет (или уже готовый сформированный документ). Рассмотрим пример кода:


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

Во-вторых, вызовем эту функцию с клиента. Стоит помнить, что сам объект Макет (если это табличный документ) можно передавать между сервером и клиентом, однако работать с ним (редактировать, выводить области) эффективнее на сервере.

Оптимизация клиент-серверного взаимодействия

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

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


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

Формирование печатной формы: пошаговый алгоритм

Зачастую макет нужен не сам по себе, а для заполнения данными и вывода пользователю. Посмотрим на пример полной процедуры печати, где мы передаем ТабличныйДокумент с сервера на клиент.

Шаг 1. Описываем логику на сервере:


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

Шаг 2. Вызываем печать на клиенте:


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

Особенности работы с Active Document (Word, Excel)

Рассмотрим ситуацию, когда макет представляет собой шаблон Word или Excel. В этом случае обычная передача макета через Возврат может вызвать ошибку «Неизвестный тип». Это происходит потому, что такие макеты на сервере инициализируются как COM-объекты, которые нельзя передать на клиент напрямую.

Проанализируем решение этой проблемы:

  1. На сервере извлекаем макет как ДвоичныеДанные.
  2. Помещаем эти данные во временное хранилище с помощью функции ПоместитьВоВременноеХранилище().
  3. Передаем адрес хранилища на клиент.
  4. На клиенте получаем данные, сохраняем их во временный файл и открываем через COM-объект (Word.Application).

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

Если формирование отчета занимает длительное время, рекомендуется выполнять его в фоновом задании. В этом случае метод РеквизитФормыВЗначение будет недоступен, так как фоновое задание не имеет контекста формы. Выясним, как поступить в этом случае: необходимо передавать в фоновое задание ссылку на обработку или её двоичные данные, чтобы сервер мог самостоятельно инициализировать объект ВнешняяОбработка и обратиться к его макетам.

Рекомендации по интеграции с БСП

В современных конфигурациях (например, БП 3.0, УТ 11, ERP) правильнее не писать код получения макета вручную в форме, а использовать подсистему «Печать». Для этого:

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

Подводя итог, отметим, что ключ к успешной работе с макетами во внешних обработках на УФ — это четкое понимание того, на какой стороне (клиент или сервер) находится в данный момент контекст выполнения и использование правильных инструментов для конвертации данных в программные объекты.

← На главную