Почему внешняя печатная форма открывает пустое окно в управляемом приложении 1С?

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

При разработке внешних печатных форм (ВПФ) для конфигураций на платформе 1С:Предприятие 8.3 с управляемыми формами разработчики нередко сталкиваются с ситуацией, когда печатная форма успешно подключается в справочнике дополнительных отчетов и обработок, но при попытке ее формирования на экран выводится совершенно пустое окно предварительного просмотра.

Разберем детально, почему так происходит, какие типичные ошибки допускаются в коде модуля объекта обработки и как правильно реализовать печать по стандартам Библиотеки стандартных подсистем (БСП).

Анализ типичных ошибок разработчика

Проанализируем исходный код, который часто переносят из старых конфигураций на обычных формах (или пытаются написать по наитию):


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

В данном фрагменте допущен сразу ряд грубых архитектурных ошибок:

  1. Несоответствие контракту вызова БСП. Стандартный механизм БСП при способе вызова ВызовСерверногоМетода не вызывает функцию Печать() без параметров и не ожидает от нее возврата ТабличныйДокумент. Подсистема печати вызывает специализированную процедуру с четко регламентированным списком параметров. Поскольку стандартная процедура не отрабатывает должным образом, типовое окно предпросмотра открывает пустой табличный документ.
  2. Попытка вызова метода Показать() на сервере. Добавление вызова ТабДок.Показать() на сервере приводит к критической ошибке («Интерактивные операции недоступны на сервере»). В управляемом приложении формирование документа выполняется на стороне сервера, а вывод на экран организует клиентский механизм подсистемы печати.
  3. Неверное получение макета. Вызов ПолучитьОбщийМакет("Макет") ищет макет в ветке конфигурации «Общие макеты». Макет внешней обработки должен получаться из состава самой обработки с помощью вызова ЭтотОбъект.ПолучитьМакет("Макет") или просто ПолучитьМакет("Макет") в контексте модуля объекта.
  4. Неопределенная ссылка на документ. Переменная СсылканаДок в серверном контексте не существует. Ссылки на документы, для которых сформирована команда печати, БСП передает через входной параметр — массив объектов.

Правильная реализация внешней печатной формы по стандартам БСП

Рассмотрим, как должен быть устроен модуль объекта внешней печатной формы, чтобы она корректно формировалась и открывалась в типовых конфигурациях (включая «Управление автотранспортом», «Бухгалтерию предприятия», «Управление торговлей», «ERP» и др.).

Шаг 1. Настройка функции «СведенияОВнешнейОбработке»

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


Функция СведенияОВнешнейОбработке() Экспорт
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
    
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
    ПараметрыРегистрации.Версия = "1.0";
    ПараметрыРегистрации.Назначение.Добавить("Документ.МаршрутныйЛист"); // Указываем целевой документ
    
    НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
    НоваяКоманда.Представление = НСтр("ru = 'Моя печатная форма'");
    НоваяКоманда.Идентификатор = "МояПечатнаяФорма";
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.СпособВызоваКомандыВызовСерверногоМетода();
    НоваяКоманда.ЗаменяемыеКоманды = "";
    
    Возврат ПараметрыРегистрации;
КонецФункции

Шаг 2. Реализация экспортной процедуры «Печать»

Процедура печати должна строго соблюдать интерфейс БСП и принимать четыре параметра. Документ формируется и передается в подсистему через общий модуль УправлениеПечатью:


Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
    
    Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "МояПечатнаяФорма") Тогда
        
        ТабличныйДокумент = СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати);
        
        УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
            КоллекцияПечатныхФорм,
            "МояПечатнаяФорма",
            НСтр("ru = 'Моя печатная форма'"),
            ТабличныйДокумент
        );
        
    КонецЕсли;
    
КонецПроцедуры

Шаг 3. Формирование табличного документа

Вынесем алгоритм формирования печатного листа в отдельную функцию. Обратите внимание на обход массива ссылок МассивОбъектов и способ получения внутреннего макета обработки:


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

Подведем итог: чтобы избежать появления пустого окна при открытии внешней печатной формы, всегда следуйте стандартам разработки для БСП: используйте сигнатуру процедуры Печать с регистрацией документа в коллекции через УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию, получайте макет непосредственно из объекта обработки и передавайте данные для заполнения через массив выбранных объектов.

← На главную