Автоматическая печать документов по расписанию — типовая задача для складов, служб доставки и производственных цехов. Разберем, как организовать регулярную печать документов, какие нюансы работы клиент-серверной архитектуры 1С необходимо учесть и как решить вопросы с выбором конкретного сетевого принтера и лотка для бумаги.
При реализации фоновой печати часто возникает типовая ошибка: попытка вызвать метод прямой отправки на принтер непосредственно в регламентном задании. Проанализируем, почему стандартный код выдает ошибку времени выполнения.
Метод Напечатать() объекта ТабличныйДокумент имеет жесткую директиву доступности: Тонкий клиент, веб-клиент, толстый клиент, мобильное приложение (клиент). Регламентные и фоновые задания всегда выполняются на стороне сервера 1С, где графическая подсистема и прямой метод Напечатать() недоступны. При попытке вызова этого метода на сервере платформа сгенерирует исключение.
Существуют два рабочих подхода к реализации автоматической печати без участия оператора:
Рассмотрим наиболее стабильный и поддерживаемый вариант. На выделенном компьютере или виртуальной машине запускается тонкий клиент 1С. В модуле управляемого приложения или в специальной обработке запускается регламентная процедура с помощью метода ПодключитьОбработчикОжидания().
Разберем по шагам логику формирования и отправки документов на принтер. Процедура выборки данных обращается к серверу, формирует табличные документы и передает их клиенту для непосредственной печати.
Посмотрим на пример кода обработки очереди документов в клиентском контексте:
// Клиентский метод обработки очереди
&НаКлиенте
Процедура ОбработатьОчередьПечати()
// Получаем список документов для печати с сервера
МассивСсылок = ПолучитьНенапечатанныеЗаказыНаСервере();
Для Каждого СсылкаНаДокумент Из МассивСсылок Цикл
// Формируем печатную форму на стороне сервера
ТабДок = СформироватьПечатнуюФормуНаСервере(СсылкаНаДокумент);
Если ТабДок <> Неопределено Тогда
// Задаем принтер из настроек или констант
ТабДок.ИмяПринтера = ПолучитьИмяПринтераПоУмолчанию();
// Задаем параметры страницы
ТабДок.РазмерСтраницы = "A4";
// Выполняем прямую печать без вывода интерактивного диалога
ТабДок.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
// Фиксируем признак успешной печати в базе
УстановитьПризнакНапечатанНаСервере(СсылкаНаДокумент);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
В модуле объекта документа или в общем модуле процедура формирования макета должна возвращать готовый ТабличныйДокумент. Обратите внимание, что метод ТабличныйДокумент.Напечатать() принимает параметр РежимИспользованияДиалогаПечати.НеИспользовать, благодаря чему документ уходит в очередь спулера Windows мгновенно без появления всплывающих окон.
Если развертывание отдельного сеанса-робота невозможно, разберем схему работы непосредственно в регламентном задании на сервере 1С. Поскольку сервер не может вызвать метод Напечатать(), табличный документ экспортируется в файл, а затем отправляется на печать средствами операционной системы через команду ЗапуститьПриложение().
Посмотрим на пример серверного кода:
// Метод выполняется в контексте сервера (регламентное задание)
Процедура НапечататьЗаказыНаСервере()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЗаказПокупателя.Ссылка КАК Ссылка
|ИЗ
| Документ.ЗаказПокупателя КАК ЗаказПокупателя
|ГДЕ
| НЕ ЗаказПокупателя.Напечатан";
Выборка = Запрос.Выполнить().Выбрать();
ИмяПринтера = Константы.ПринтерДляАвтоматическойПечати.Получить();
Пока Выборка.Следующий() Цикл
ДокументОбъект = Выборка.Ссылка.ПолучитьОбъект();
ТабДок = ДокументОбъект.ПечатьСчетаЗаказа("Заказ");
Если ТабДок <> Неопределено Тогда
// Формируем временный файл на диске сервера
ПутьКФайлу = ПолучитьИмяВременногоФайла("pdf");
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.PDF);
// Формируем строку запуска внешней консольной утилиты печати
// Пример использования утилиты тихой печати PDF
КоманднаяСтрока = СтрШаблон("PDFtoPrinter.exe ""%1"" ""%2""", ПутьКФайлу, ИмяПринтера);
// Запуск системного процесса печати
КодВозврата = 0;
ЗапуститьПриложение(КоманднаяСтрока, , Истина, КодВозврата);
// Фиксируем флаг печати
ДокументОбъект.Напечатан = Истина;
ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);
// Удаляем временный файл
УдалитьФайлы(ПутьКФайлу);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Выясним причину частой проблемы при печати на сервере: скрипт или утилита отрабатывают без ошибок, но документ на принтере не появляется. Служба сервера 1С (процесс ragent) обычно запускается под специальной системной учетной записью (например, usr1cv8), у которой нет пользовательского рабочего стола и подключенных сетевых принтеров.
Для гарантированной отправки заданий на печать выполним следующие настройки на сервере:
Проанализируем задачу управления лотками подачи бумаги и форматом листа, с которой столкнулся автор темы:
ТабличныйДокумент.РазмерСтраницы = "A4"; перед отправкой документа на печать или сохранением.Разберем по шагам системную настройку печати в нужный лоток:
Принтер_Склад_Лоток1 и Принтер_Склад_Лоток2).ТабличныйДокумент.ИмяПринтера передаем точное сетевое или локальное имя нужного системного принтера. При отправке задания драйвер автоматически перенаправит печать в сконфигурированный лоток.