При разработке внешних обработок на управляемых формах разработчики часто сталкиваются с задачей вывода на экран или отправки на принтер печатной формы (например, счета на оплату, накладной или отчета). Основная сложность заключается в правильном разделении контекста выполнения (клиент/сервер) и получении макета из объекта обработки.
Разберем подробно, почему макет нельзя получить напрямую из контекста управляемой формы и какие существуют проверенные способы формирования печатной формы.
Проанализируем контекст управляемой формы: объект УправляемаяФорма не имеет метода ПолучитьМакет(). Макет принадлежит метаданным внешней обработки, доступ к которым есть только у серверного объекта ВнешняяОбработкаОбъект.
Чтобы обратиться к макету из модуля формы, необходимо преобразовать основной реквизит формы в прикладной объект с помощью функции РеквизитФормыВЗначение(). Выполнять эту операцию следует строго в серверном контексте (директива &НаСервере или &НаСервереБезКонтекста).
Рассмотрим классический вариант, когда по нажатию кнопки на форме табличный документ формируется на сервере и открывается пользователю для просмотра на клиенте.
Разберем по шагам реализацию обработчика команды:
ТабличныйДокумент.Показать() или отправляем напрямую на печать.Посмотрим на пример кода в модуле управляемой формы:
&НаКлиенте
Процедура Печать(Команда)
// Формируем табличный документ на стороне сервера
ТабДок = СформироватьСчетНаСервере();
// Отображаем сформированную печатную форму пользователю
ТабДок.Показать("Печать счета на оплату");
КонецПроцедуры
&НаСервере
Функция СформироватьСчетНаСервере()
// Получаем прикладной объект обработки из реквизита формы
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
// Получаем макет из метаданных обработки
Макет = ОбработкаОбъект.ПолучитьМакет("МакетСчета");
ТабДок = Новый ТабличныйДокумент;
// Настраиваем параметры вывода
ТабДок.Автомасштаб = Истина;
ТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
// Получаем и заполняем области макета
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
// Заполнение параметров: ОбластьШапка.Параметры.Номер = Объект.Номер;
ТабДок.Вывести(ОбластьШапка);
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
// В цикле заполняем и выводим строки: ТабДок.Вывести(ОбластьСтрока);
ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
ТабДок.Вывести(ОбластьПодвал);
Возврат ТабДок;
КонецФункции
Если в форме обработки предусмотрено специальное поле для предпросмотра (реквизит формы с типом ТабличныйДокумент, например, с именем ДокументРезультат), открывать отдельное окно через Показать() не требуется.
Рассмотрим, как выглядит заполнение реквизита формы:
&НаСервере
Процедура СформироватьСчетВПолеФормы()
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
Макет = ОбработкаОбъект.ПолучитьМакет("МакетСчета");
// Очищаем существующий табличный документ на форме
ДокументРезультат.Очистить();
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ДокументРезультат.Вывести(ОбластьШапка);
// Дальнейший вывод областей в ДокументРезультат
КонецПроцедуры
Для соблюдения чистоты архитектуры код формирования печатной формы часто выносят в модуль объекта. В таком случае в модуле формы только делегируют вызов объекту:
В модуле объекта внешней обработки объявляем экспортную процедуру:
Процедура СформироватьСчет(ТабДок) Экспорт
Макет = ПолучитьМакет("МакетСчета");
ТабДок.Очистить();
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ТабДок.Вывести(ОбластьШапка);
// Заполнение остальных секций макета
КонецПроцедуры
В модуле формы вызываем данный метод:
&НаСервере
Процедура ПечатьНаСервере()
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
// Передаем табличный документ (реквизит формы) в модуль объекта
ОбработкаОбъект.СформироватьСчет(ДокументРезультат);
КонецПроцедуры
Если конфигурация разработана с использованием Библиотеки Стандартных Подсистем (БСП) и обработка должна подключаться как внешняя печатная форма к типовым документам или справочникам, форма обработки вовсе не требуется.
Проанализируем структуру модуля объекта для БСП:
СведенияОВнешнейОбработке(), которая регистрирует команду печати.Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода).УправлениеПечатью.ИнициализироватьКоллекциюПечатныхФорм, УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию).Такой подход обеспечивает единый пользовательский интерфейс типовой конфигурации: отправку по почте, сохранение в PDF/Excel, факсимиле и управление комплектами печати.
Обратим внимание на несколько критически важных моментов:
Показать() и Напечатать() доступны исключительно на клиенте. Попытка вызвать их на сервере приведет к синтаксической ошибке выполнения.ТабДок.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать); или РежимИспользованияДиалогаПечати.Использовать.ТабДок.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_ВнешняяОбработка_Счет";.