В процессе автоматизации бизнес-процессов часто возникает задача отправлять документы на печать прямо из кода, без каких-либо диалоговых окон и предварительного просмотра. Например, нужно распечатать УПД или счет-фактуру по ссылке на документ реализации. Давайте разберем, как реализовать такую печать в конфигурации "Управление торговлей 11.4" для стандартных и внешних печатных форм. Для настройки пакетной отправки комплектов в УТ можно использовать расширение для печати связанных документов заказа, позволяющее автоматизировать этот процесс.
Основная проблема, с которой сталкиваются разработчики, — это вызов стандартных процедур печати, которые по умолчанию открывают табличный документ на экране для просмотра. Нам же требуется отправить его сразу на принтер, установленный по умолчанию или даже на конкретный, указанный в коде.
Библиотека стандартных подсистем (БСП) предоставляет готовые инструменты для работы с печатью. Часто по ошибке для вывода на печать используют процедуру УправлениеПечатьюКлиент.ВыполнитьКомандуПечати. Она отлично подходит для интерактивной работы пользователя, но всегда показывает окно предварительного просмотра.
Для нашей задачи — отправки документа сразу на принтер — предназначена другая процедура: <strong>УправлениеПечатьюКлиент.ВыполнитьКомандуПечатиНаПринтер</strong>. Проанализируем, как ей правильно пользоваться.
Часто совершают ошибку, передавая в качестве идентификатора команды печати имя макета, как в примере ниже:
// НЕПРАВИЛЬНЫЙ ВАРИАНТ
УправлениеПечатьюКлиент.ВыполнитьКомандуПечатиНаПринтер(
"Обработка.ПечатьОбщихФорм",
"ПФ_MXL_УниверсальныйПередаточныйДокумент_ru", // Ошибка: это имя макета, а не идентификатор
МассивОбъектов,
Неопределено,
Неопределено
);
Такой вызов не сработает. Вторым параметром процедура ожидает не имя макета, а уникальный идентификатор команды печати. Для УПД это "УПД", для счета на оплату — "СчетЗаказ" и так далее.
Где найти правильный идентификатор команды?
Найти его можно в модуле менеджера нужного объекта (например, документа "РеализацияТоваровУслуг") в процедуре ДобавитьКомандыПечати. Там регистрируются все доступные для этого объекта печатные формы.
Рассмотрим правильный пример кода для печати УПД для документа "Реализация товаров и услуг" сразу на принтер.
&НаКлиенте
Процедура ПечатьУПДНаПринтер(СсылкаНаДокумент)
// Объект печати должен быть в виде массива,
// даже если документ всего один.
МассивОбъектов = Новый Массив;
МассивОбъектов.Добавить(СсылкаНаДокумент);
// Вызываем правильную процедуру с правильным идентификатором
УправлениеПечатьюКлиент.ВыполнитьКомандуПечатиНаПринтер(
"Документ.РеализацияТоваровУслуг", // Имя объекта-владельца команды
"УПД", // Идентификатор команды печати
МассивОбъектов, // Массив ссылок на документы
Неопределено // Здесь можно указать имя конкретного принтера в виде строки
);
КонецПроцедуры
Этот метод является наиболее корректным, так как использует штатный механизм БСП, который учитывает различные настройки, права доступа и другие нюансы системы.
Существует и другой подход — сформировать табличный документ на сервере, вернуть его на клиент и уже там отправить на печать. Этот способ дает больше контроля над процессом, но является, по сути, "обходом" стандартного менеджера печати БСП.
Алгоритм действий следующий:
ПечатьОбщихФорм), которая отвечает за формирование нужной печатной формы.ТабличныйДокумент.Напечатать() с параметром, отключающим диалог печати.Посмотрим на пример кода:
&НаКлиенте
Процедура ПрямаяПечатьУПД(СсылкаНаДокумент)
ТабличныйДокумент = СформироватьУПДНаСервере(СсылкаНаДокумент);
// Перед печатью можно задать дополнительные параметры
// ТабличныйДокумент.ИмяПринтера = "MySecondPrinter";
// ТабличныйДокумент.КоличествоЭкземпляров = 2;
ТабличныйДокумент.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
КонецПроцедуры
&НаСервере
Функция СформироватьУПДНаСервере(СсылкаНаДокумент)
МассивОбъектов = Новый Массив;
МассивОбъектов.Добавить(СсылкаНаДокумент);
// Параметры печати можно оставить пустыми, если не требуется
// передавать специфичные настройки в процедуру формирования
ПараметрыПечати = Новый Структура;
// Вызываем экспортную функцию общего модуля, которая формирует печатную форму
ТабДок = ПечатьОбщихФорм.СформироватьПечатнуюФорму("УПД", МассивОбъектов, ПараметрыПечати);
Возврат ТабДок;
КонецФункции
Этот способ удобен, когда перед печатью нужно программно модифицировать сформированный табличный документ или гибко управлять настройками принтера (количество копий, двусторонняя печать и т.д.). При необходимости можно воспользоваться инструментом для постобработки печатных форм на базе БСП, позволяющим изменять готовые макеты без вмешательства в программный код.
Задача усложняется, если нужно распечатать не встроенную, а внешнюю печатную форму. Стандартный вызов через общую форму ПечатьДокументов откроет диалоговое окно, что нам не подходит.
Решение здесь схоже со вторым способом: необходимо программно подключить внешнюю обработку, вызвать из нее экспортную процедуру формирования печатной формы, получить табличный документ и распечатать его на клиенте.
Разберем процесс по шагам.
ДополнительныеОтчетыИОбработки.Подключить(), чтобы получить безопасное временное имя файла обработки. Затем создаем объект внешней обработки через ВнешниеОбработки.Создать().Печать(). Мы должны вызвать ее, передав необходимые параметры: массив объектов, коллекцию печатных форм и т.д.Печать() заполнит переданный ей по ссылке объект ТабличныйДокумент. Мы возвращаем этот объект на клиент и печатаем его методом Напечатать().Пример реализации:
&НаКлиенте
Процедура ПечатьВнешнейФормыНаПринтер(СсылкаНаДокумент, СсылкаНаВПФ)
ТабДок = ПолучитьТабличныйДокументВПФНаСервере(СсылкаНаВПФ, СсылкаНаДокумент);
Если ТабДок <> Неопределено И ТабДок.ВысотаТаблицы > 0 Тогда
ТабДок.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
Иначе
// Обработать ситуацию, когда печатная форма не сформировалась
ПоказатьПредупреждение(,"Не удалось сформировать печатную форму.");
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция ПолучитьТабличныйДокументВПФНаСервере(СсылкаНаВПФ, СсылкаНаДокумент)
ТабличныйДокумент = Неопределено;
// 1. Подключаем внешнюю обработку
ИмяОбработки = ДополнительныеОтчетыИОбработки.Подключить(СсылкаНаВПФ);
Если ИмяОбработки = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ВнешняяОбработка = ВнешниеОбработки.Создать(ИмяОбработки, Ложь); // Ложь - безопасный режим
// 2. Готовим параметры для вызова процедуры печати
МассивОбъектов = Новый Массив;
МассивОбъектов.Добавить(СсылкаНаДокумент);
КоллекцияПечатныхФорм = Новый КоллекцияПечатныхФорм;
ПараметрыВывода = Новый Структура;
ОбъектыПечати = Новый СписокЗначений;
РезультатПечати = Новый ТабличныйДокумент;
// 3. Вызываем экспортную процедуру печати из модуля объекта ВПФ
// Название процедуры "Печать" является стандартным для ВПФ.
// Если в вашей ВПФ она называется иначе, укажите правильное имя.
Попытка
ВнешняяОбработка.Печать(
МассивОбъектов,
КоллекцияПечатныхФорм,
ОбъектыПечати,
РезультатПечати,
ПараметрыВывода
);
ТабличныйДокумент = РезультатПечати;
Исключение
// Логирование или вывод ошибки
ЗаписьЖурналаРегистрации("Ошибка печати ВПФ", УровеньЖурналаРегистрации.Ошибка, , , ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
Возврат Неопределено;
КонецПопытки;
Возврат ТабличныйДокумент;
КонецФункции
Таким образом, мы можем автоматизировать печать не только встроенных, но и любых внешних печатных форм, полностью контролируя процесс из кода.