В процессе разработки на платформе 1С:Предприятие 8.3 мы часто сталкиваемся с архитектурным ограничением: метод Напечатать() объекта ТабличныйДокумент доступен исключительно в клиентском контексте. Это создает серьезные трудности при работе с HTTP-сервисами, Web-сервисами или фоновыми заданиями, где код выполняется на стороне сервера, а печать должна произойти автоматически без участия пользователя.
В этой статье мы подробно разберем, почему стандартные методы не работают, и рассмотрим несколько эффективных стратегий решения задачи: от использования системных команд операционной системы до создания специализированных "агентов печати". Для настройки регулярного взаимодействия между базами 1С в рамках подобных стратегий настраивается автоматический обмен по расписанию.
Разберем ситуацию: сервер 1С — это консольное приложение, работающее в контексте службы Windows. У него нет графического интерфейса (GUI) и прямой связи с драйверами принтера, которые установлены в пользовательской сессии. Платформа 1С жестко разделяет функционал, и все, что касается вывода на устройства печати, делегировано клиенту. Даже попытка использовать ПакетОтображаемыхДокументов или COM-соединение часто заканчивется ошибкой "Метод недоступен на сервере".
Один из самых быстрых способов реализации — сохранение документа во временный файл формата PDF и его последующая отправка на печать через системный глагол операционной системы. Рассмотрим этот метод подробнее.
Проанализируем пример кода, который можно выполнить в серверном модуле:
// 1. Формируем табличный документ
ТабДок = Новый ТабличныйДокумент;
// ... заполнение документа данными ...
// 2. Сохраняем во временный файл PDF
ИмяФайла = ПолучитьИмяВременногоФайла("pdf");
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.PDF);
// 3. Вызываем печать через COM-объект Shell
Попытка
Shell = Новый COMОбъект("Shell.Application");
Shell.ShellExecute(ИмяФайла, "", "", "print", 0);
Исключение
ЗаписьЖурналаРегистрации("Печать на сервере", УровеньЖурналаРегистрации.Ошибка, , , ПодробноеОписаниеОшибки());
КонецПопытки;
Важный нюанс: этот метод сильно зависит от того, какое приложение в системе назначено программой по умолчанию для просмотра PDF. Если это Adobe Reader, он может остаться открытым в памяти сервера после печати, что со временем приведет к утечке ресурсов. Выясним, как сделать процесс более надежным.
Для более профессиональной и стабильной работы на сервере лучше использовать специализированные утилиты, поддерживающие "тихую" печать (без открытия окон). Одной из самых популярных является SumatraPDF.
Рассмотрим алгоритм настройки:
ЗапуститьПриложение().Посмотрим на пример реализации:
ПутьКПрограмме = """C:\Program Files\SumatraPDF\SumatraPDF.exe""";
ИмяПринтера = "HP_LaserJet_Pro_M402"; // Имя принтера в системе
ПутьКФайлу = "D:\Temp\doc_to_print.pdf";
// Командная строка для тихой печати на конкретный принтер
Команда = ПутьКПрограмме + " -print-to """ + ИмяПринтера + """ -silent " + ПутьКФайлу;
ЗапуститьПриложение(Команда, , Истина); // Истина - ждать завершения
Преимущество этого метода в том, что процесс полностью скрыт от пользователя и корректно завершается после отправки документа в очередь печати. Для выполнения технического обслуживания, обновления и проверки баз в подобном скрытом режиме используется автоматическое тестирование и обновление баз.
Если инфраструктура не позволяет устанавливать стороннее ПО на сервер, применим метод с использованием "Агента печати". Суть заключается в разделении ответственности: сервер только создает задание, а постоянно запущенный клиентский сеанс его выполняет.
Разберем по шагам создание такой системы:
ОчередьПечати.Идентификатор (УникальныйИдентификатор), ДанныеДокумента (ХранилищеЗначения), Статус (Перечисление или Строка), ИмяПринтера.Код на сервере (например, в HTTP-сервисе) будет выглядеть так:
НоваяЗапись = РегистрыСведений.ОчередьПечати.СоздатьМенеджерЗаписи();
НоваяЗапись.Идентификатор = Новый УникальныйИдентификатор();
НоваяЗапись.ДанныеДокумента = Новый ХранилищеЗначения(ТабДок);
НоваяЗапись.Статус = "ВРаботе";
НоваяЗапись.Записать();
Затем на клиентском компьютере, подключенном к принтеру, запускаем сеанс 1С под служебным пользователем, где в модуле приложения подключаем обработчик ожидания:
Процедура ПриНачалеРаботыСистемы()
ПодключитьОбработчикОжидания("ПроверитьОчередьПечати", 5); // Проверка каждые 5 секунд
КонецПроцедуры
Процедура ПроверитьОчередьПечати() Экспорт
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 Идентификатор, ДанныеДокумента ИЗ РегистрСведений.ОчередьПечати ГДЕ Статус = ""ВРаботе""";
// ... выполнение запроса ...
// Если запись найдена:
ТабДок = Выборка.ДанныеДокумента.Получить();
ТабДок.Напечатать(РежимИспользованияПринтера.БезПредварительногоПросмотра);
// Удаляем запись или меняем статус
КонецПроцедуры
Проанализируем критический аспект, о котором часто забывают. Когда сервер 1С запущен как служба, он работает в так называемой "Сессии 0". В этой сессии принтеры, установленные для обычного пользователя, могут быть недоступны.
Рекомендации для системного администратора:
System или той учетной записи, от имени которой работает служба 1C:Enterprise Server.\\Server\Printer), проверьте права доступа учетной записи сервера к этому ресурсу.Мы рассмотрели три основных пути решения проблемы печати на сервере. Выбор метода зависит от ваших требований:
Применяя эти подходы, вы сможете автоматизировать печать документов в самых сложных интеграционных сценариях, обеспечивая мгновенный отклик системы на внешние запросы. Для автоматизации формирования документов и выполнения других повторяющихся действий в условиях отсутствия прямого API применяется платформа для создания программных роботов.