В процессе разработки автоматизированных систем на платформе 1С:Предприятие 8.3 часто возникает задача реализации массовой или пакетной печати документов. Пользователям удобно нажать одну кнопку и получить стопку распечатанных счетов или актов, вместо того чтобы открывать каждый документ по отдельности. В этой статье мы разберем, как правильно организовать программный код для решения этой задачи, учитывая особенности клиент-серверного взаимодействия и современные стандарты разработки в конфигурациях типа УТ 11.4, ERP или КА 2.
Давайте проанализируем ситуацию: у нас есть реестр документов (например, в таблице значений на форме), и нам нужно отправить их на принтер. Основная сложность заключается в том, что формирование печатной формы (заполнение макета данными) происходит на сервере, а непосредственная отправка на принтер возможна только на клиенте. Рассмотрим пошагово, как выстроить этот процесс.
Для начала определимся с алгоритмом:
ТабличныйДокумент.Напечатать() для каждого документа.Рассмотрим пример кода, который подготавливает документы. Важно понимать, что в современных конфигурациях логика печати часто вынесена в модули менеджеров. Посмотрим на реализацию функции, которая собирает табличные документы в массив:
&НаСервере
Функция СформироватьПакетДокументовНаСервере(МассивСсылок)
МассивТабДоков = Новый Массив;
Для Каждого Ссылка Из МассивСсылок Цикл
// В типовых конфигурациях (БСП) лучше использовать менеджер печати
// Но для понимания сути рассмотрим прямой вызов
ДокОбъект = Ссылка.ПолучитьОбъект();
// Предположим, у документа есть экспортная процедура Печать
// которая возвращает ТабличныйДокумент
ТабДок = ДокОбъект.СформироватьПечатнуюФорму();
Если ТабДок <> Неопределено Тогда
МассивТабДоков.Добавить(ТабДок);
КонецЕсли;
КонецЦикла;
Возврат МассивТабДоков;
КонецФункции
Обратите внимание на важный нюанс: если мы работаем в УТ 11.4, печать счета или другого документа может быть вынесена в отдельную обработку или находиться в модуле менеджера. В таком случае вместо ДокументОбъект.ПолучитьОбъект() мы будем обращаться к менеджеру документа или использовать программный интерфейс БСП.
Если ваша конфигурация построена на базе БСП, мы крайне рекомендуем использовать стандартный механизм УправлениеПечатью. Это позволит избежать написания лишнего кода и обеспечит стабильность работы. Проанализируем пример вызова печати через БСП:
// Пример вызова через общие модули БСП
УправлениеПечатью.СформироватьПечатныеФормы(ИмяМенеджераПечати, ИменаМакетов, МассивОбъектов, ПараметрыПечати, КоллекцияПечатныхФорм, ОбъектыПечати, ВыводитьСразу);
Этот метод оптимизирован для работы с большими объемами данных. Он формирует структуру, которую легко передать на клиент для последующего вывода. Для изменения и доработки сформированных документов подойдёт решение для постобработки печатных форм на основе методов БСП.
После того как сервер вернул нам массив ТабличныйДокумент, мы должны отправить их на печать. Нам нужно решить, хотим ли мы показывать диалоговое окно выбора принтера для каждого документа или напечатать всё "тихо".
&НаКлиенте
Процедура ВыполнитьПечать(МассивТабДоков)
Для Каждого ТекущийТабДок Из МассивТабДоков Цикл
// Настройка параметров печати
ТекущийТабДок.ИмяПринтера = "HP_LaserJet_Pro_400"; // Можно задать конкретный принтер
ТекущийТабДок.КоличествоЭкземпляров = 1;
// Метод Напечатать() выводит документ на принтер
// Параметр РежимИспользованияДиалогаПечати.НеИспользовать позволяет печатать без лишних вопросов
ТекущийТабДок.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
КонецЦикла;
КонецПроцедуры
Рассмотрим ситуацию, когда документов очень много. Если отправлять каждый ТабличныйДокумент методом Напечатать(), в очереди печати Windows создастся множество заданий. Это может привести к тому, что листы разных документов перемешаются в лотке принтера, если в этот момент кто-то еще отправит файл на печать. Для решения этой проблемы разберем объект ПакетОтображаемыхДокументов.
ПакетОтображаемыхДокументов позволяет объединить несколько табличных документов в одно задание на печать. Это гарантирует целостность пачки и корректную работу двусторонней печати.
&НаКлиенте
Процедура ПечатьПакетом(МассивТабДоков)
Пакет = Новый ПакетОтображаемыхДокументов;
Для Каждого ТабДок Из МассивТабДоков Цикл
ЭлементПакета = Пакет.Состав.Добавить();
ЭлементПакета.Данные = ТабДок;
КонецЦикла;
// Печать всего пакета как одного задания
Пакет.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
КонецПроцедуры
Выясним причину, по которой в УТ 11.4 печать некоторых документов (например, счета на оплату) может казаться сложнее. Разработчики часто выносят логику в менеджеры или отдельные обработки для унификации интерфейса. При программной печати в такой среде важно:
ДополнительныеОтчетыИОбработки.ОбъектВнешнейОбработки(Ссылка).Печать в модуле менеджера обычно ожидает массив ссылок. Это позволяет серверу выполнить один запрос к базе данных вместо множества мелких запросов в цикле.Мы проанализировали основные подходы к автоматизации печати. Подведем итог: для качественной реализации всегда разделяйте подготовку данных и их визуализацию. Используйте ПакетОтображаемыхДокументов для надежности и Библиотеку стандартных подсистем для минимизации ошибок. Если ваша задача требует сохранения документов в PDF для рассылки, платформа также позволяет объединять табличные документы в один файл, что логически схоже с формированием пакета для печати. При необходимости нанесения дополнительных реквизитов на итоговые файлы можно использовать обработку для добавления штампа в PDF средствами платформы 1С.