При разработке внешних печатных форм (ВПФ) для конфигураций на платформе 1С:Предприятие 8.3 с управляемыми формами разработчики нередко сталкиваются с ситуацией, когда печатная форма успешно подключается в справочнике дополнительных отчетов и обработок, но при попытке ее формирования на экран выводится совершенно пустое окно предварительного просмотра.
Разберем детально, почему так происходит, какие типичные ошибки допускаются в коде модуля объекта обработки и как правильно реализовать печать по стандартам Библиотеки стандартных подсистем (БСП).
Проанализируем исходный код, который часто переносят из старых конфигураций на обычных формах (или пытаются написать по наитию):
Функция Печать() Экспорт
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьОбщийМакет("Макет");
Область = Макет.ПолучитьОбласть("Область");
Область.Параметры.ДатаДок = Формат(СсылканаДок.ДокументОснование.Дата, "ДЛФ=DD");
// Заполнение параметров...
ТабДок.Вывести(Область);
Возврат ТабДок;
КонецФункции
В данном фрагменте допущен сразу ряд грубых архитектурных ошибок:
ВызовСерверногоМетода не вызывает функцию Печать() без параметров и не ожидает от нее возврата ТабличныйДокумент. Подсистема печати вызывает специализированную процедуру с четко регламентированным списком параметров. Поскольку стандартная процедура не отрабатывает должным образом, типовое окно предпросмотра открывает пустой табличный документ.Показать() на сервере. Добавление вызова ТабДок.Показать() на сервере приводит к критической ошибке («Интерактивные операции недоступны на сервере»). В управляемом приложении формирование документа выполняется на стороне сервера, а вывод на экран организует клиентский механизм подсистемы печати.ПолучитьОбщийМакет("Макет") ищет макет в ветке конфигурации «Общие макеты». Макет внешней обработки должен получаться из состава самой обработки с помощью вызова ЭтотОбъект.ПолучитьМакет("Макет") или просто ПолучитьМакет("Макет") в контексте модуля объекта.СсылканаДок в серверном контексте не существует. Ссылки на документы, для которых сформирована команда печати, БСП передает через входной параметр — массив объектов.Рассмотрим, как должен быть устроен модуль объекта внешней печатной формы, чтобы она корректно формировалась и открывалась в типовых конфигурациях (включая «Управление автотранспортом», «Бухгалтерию предприятия», «Управление торговлей», «ERP» и др.).
Подсистема дополнительных отчетов и обработок БСП считывает метаданные из экспортной функции СведенияОВнешнейОбработке(). Объявим команду печати со способом вызова ВызовСерверногоМетода:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
ПараметрыРегистрации.Версия = "1.0";
ПараметрыРегистрации.Назначение.Добавить("Документ.МаршрутныйЛист"); // Указываем целевой документ
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = НСтр("ru = 'Моя печатная форма'");
НоваяКоманда.Идентификатор = "МояПечатнаяФорма";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.СпособВызоваКомандыВызовСерверногоМетода();
НоваяКоманда.ЗаменяемыеКоманды = "";
Возврат ПараметрыРегистрации;
КонецФункции
Процедура печати должна строго соблюдать интерфейс БСП и принимать четыре параметра. Документ формируется и передается в подсистему через общий модуль УправлениеПечатью:
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "МояПечатнаяФорма") Тогда
ТабличныйДокумент = СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати);
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"МояПечатнаяФорма",
НСтр("ru = 'Моя печатная форма'"),
ТабличныйДокумент
);
КонецЕсли;
КонецПроцедуры
Вынесем алгоритм формирования печатного листа в отдельную функцию. Обратите внимание на обход массива ссылок МассивОбъектов и способ получения внутреннего макета обработки:
Функция СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати)
ТабДок = Новый ТабличныйДокумент;
ТабДок.Автомасштаб = Истина;
// Получаем макет из самой внешней обработки
Макет = ЭтотОбъект.ПолучитьМакет("Макет");
ОбластьДанные = Макет.ПолучитьОбласть("Область");
НомерСтрокиНачало = 1;
Для Каждого СсылкаНаДок Из МассивОбъектов Цикл
// Заполняем параметры области макета данными текущего документа
ОбластьДанные.Параметры.ДатаДок = Формат(СсылкаНаДок.Дата, "ДЛФ=DD");
Если ЗначениеЗаполнено(СсылкаНаДок.ДокументОснование) Тогда
ОбластьДанные.Параметры.ДатаПодан = Формат(СсылкаНаДок.ДокументОснование.ОтправлениеС, "ДФ=dd.MM.yyyy");
ОбластьДанные.Параметры.Время = Формат(СсылкаНаДок.ДокументОснование.ОтправлениеС, "ДЛФ=T");
ОбластьДанные.Параметры.Маршрут = Строка(СсылкаНаДок.ДокументОснование.АдресОтправления) + " - " +
Строка(СсылкаНаДок.ДокументОснование.АдресНазначения);
КонецЕсли;
ТабДок.Вывести(ОбластьДанные);
// Регистрируем область печати для текущего объекта
УправлениеПечатью.ЗадатьОбластьПечатиДокумента(ТабДок, НомерСтрокиНачало, ОбъектыПечати, СсылкаНаДок);
НомерСтрокиНачало = ТабДок.ВысотаТаблицы + 1;
КонецЦикла;
Возврат ТабДок;
КонецФункции
Подведем итог: чтобы избежать появления пустого окна при открытии внешней печатной формы, всегда следуйте стандартам разработки для БСП: используйте сигнатуру процедуры Печать с регистрацией документа в коллекции через УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию, получайте макет непосредственно из объекта обработки и передавайте данные для заполнения через массив выбранных объектов.