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