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