При автоматизации складской и торговой логистики часто возникает задача быстрой подготовки комплектов документов (например, УПД, ТТН, транспортная накладная, сертификаты соответствия). Для экономии времени сотрудников офиса или склада используются высокопроизводительные принтеры и МФУ со встроенными финишерами-степлерами, такие как RICOH SP 8400DN. Однако разработчики сталкиваются с серьезным аппаратным ограничением: автоматический степлер принтера может скреплять только те страницы, которые пришли в рамках одного задания печати (Print Job).
Если отправлять документы из 1С стандартным методом по очереди, операционная система Windows формирует для каждого документа отдельное задание печати. В результате принтер печатает документы отдельно и не может физически скрепить их в один комплект. Ситуация усложняется, если разные документы в пакете должны печататься из разных лотков (например, наклейки на коробки из обходного лотка, а УПД — из основного), а также иметь разную ориентацию (портрет/ландшафт) и режим цветности или двусторонней печати (дуплекс).
В этой статье мы подробно разберем четыре практических метода решения этой проблемы, начиная от штатных механизмов платформы 1С и заканчивая низкоуровневым управлением потоком печати.
---
В платформе 1С:Предприятие существует специализированный объект ПакетОтображаемыхДокументов. Он предназначен для объединения нескольких табличных документов в один пакет для последующей отправки на печать или сохранения.
Важное ограничение: в старых версиях платформы (8.3.7 и ниже) или при включенном режиме совместимости с этими версиями метод Напечатать() этого объекта все равно разбивает пакет на отдельные задания печати в операционной системе. Начиная с версии платформы 8.3.9 (при условии отключения режима совместимости со старыми версиями), поведение метода было изменено для ОС Windows: теперь весь пакет отправляется на принтер одним заданием, даже если входящие в него документы имеют разные параметры страниц (ориентацию, масштаб и т.д.).
Рассмотрим пример кода, как правильно сформировать и отправить пакет документов на печать из 1С:
// Создаем объект пакета документов
ПакетДокументов = Новый ПакетОтображаемыхДокументов;
// Настраиваем общие параметры пакета, если необходимо
ПакетДокументов.ИмяПринтера = "RICOH SP 8400DN";
// Формируем первый документ (например, УПД)
ТабДокУПД = СформироватьПечатнуюФормуУПД();
ТабДокУПД.ИмяПараметровПечати = "ПараметрыПечати_УПД";
// Укажем двустороннюю печать для УПД
ТабДокУПД.ДвусторонняяПечать = ДвусторонняяПечать.Двусторонняя;
ЭлементПакета1 = ПакетДокументов.Состав.Добавить();
ЭлементПакета1.Данные = ТабДокУПД;
// Формируем второй документ (ТТН)
ТабДокТТН = СформироватьПечатнуюФормуТТН();
ТабДокТТН.ИмяПараметровПечати = "ПараметрыПечати_ТТН";
// ТТН печатаем с одной стороны
ТабДокТТН.ДвусторонняяПечать = ДвусторонняяПечать.Односторонняя;
ЭлементПакета2 = ПакетДокументов.Состав.Добавить();
ЭлементПакета2.Данные = ТабДокТТН;
// Отправляем на печать одним заданием
ПакетДокументов.Напечатать(Истина);
Если ваша конфигурация работает на современной платформе без старого режима совместимости, данный код решит проблему: принтер примет один документ-пакет, применит настройки двусторонней печати к нужным страницам и автоматически скрепит готовый комплект скрепкой.
---
Если ваша база данных работает на старой конфигурации (например, 1С:Управление торговлей 10.3 на обычном интерфейсе) и обновить режим совместимости платформы невозможно, метод ПакетОтображаемыхДокументов.Напечатать() будет разбивать задание. В этом случае мы можем пойти другим путем: сохранить весь пакет в один PDF-файл с помощью метода ЗаписатьФайлДляПечати().
Однако при этом теряются индивидуальные настройки лотков и двусторонней печати для отдельных документов внутри PDF. Чтобы обойти это ограничение, мы можем использовать интеллектуальные возможности профессионального драйвера принтера RICOH (драйверы класса PCL6 или PostScript).
Проанализируем пошагово, как реализовать этот подход:
RICOH_Stapled_Kit. Это позволит не сбивать стандартные настройки печати для других задач.RICOH_Stapled_Kit, перейдите в «Настройки печати» (Printing Preferences) и найдите вкладку «Исключения страниц» (Page Exceptions / Special Pages).
Лотка 1 (где лежит обычная бумага).Лотка 2 (где лежит цветная подложка или бланки) и печататься в режиме Duplex.
// Формируем пакет документов
ПакетДокументов = Новый ПакетОтображаемыхДокументов;
ТабДок1 = ПолучитьТабличныйДокумент1();
Элемент1 = ПакетДокументов.Состав.Добавить();
Элемент1.Данные = ТабДок1;
ТабДок2 = ПолучитьТабличныйДокумент2();
Элемент2 = ПакетДокументов.Состав.Добавить();
Элемент2.Данные = ТабДок2;
// Записываем единый PDF-файл во временный каталог
ПутьКФайлуPDF = КаталогВременныхФайлов() + "packet_to_print.pdf";
ПакетДокументов.ЗаписатьФайлДляПечати(ПутьКФайлуPDF);
// Отправляем PDF на печать на специализированный принтер с преднастроенными исключениями
// Для отправки PDF на печать из кода можно использовать системную утилиту PDFtoPrinter или Adobe Reader
ИмяПринтера = "RICOH_Stapled_Kit";
КомандаЗапуска = """" + КаталогПрограммы() + "PDFtoPrinter.exe"" """ + ПутьКФайлуPDF + """ """ + ИмяПринтера + """";
ЗапуститьПриложение(КомандаЗапуска, , Истина);
Преимущества метода: Работает на абсолютно любой версии 1С и платформы. Надежное сшивание степлером гарантировано, так как операционная система отправляет ровно один файл в очередь печати.
Минусы метода: Подходит только для пакетов документов с жестко фиксированной структурой страниц (когда мы точно знаем, что УПД всегда занимает 2 страницы, а спецификация — 4). Если количество страниц динамически меняется, правила «Исключений страниц» в драйвере настроить не удастся.
---
Если структура документов в пакете динамическая (количество страниц заранее неизвестно), но печать из разных лотков с автоматическим скреплением жизненно необходима, мы можем использовать внешние утилиты командной строки (CLI), которые поддерживают передачу параметров выбора лотка для конкретных диапазонов страниц динамически.
Одной из популярных утилит для таких задач является VeryPDF PDF Print Command Line или аналогичный софт (например, Print Conductor).
Разберем пример реализации, при котором мы динамически анализируем количество страниц в каждом документе внутри 1С, формируем один PDF-файл, а затем вызываем внешнюю утилиту командной строки, передавая ей карту лотков в параметрах:
// Предположим, мы выяснили программно количество страниц в документах
СтраницВПервомДокументе = 3; // УПД
СтраницВоВторомДокументе = 2; // Сертификат
// Формируем единый файл PDF из 1С
ПутьКФайлуPDF = КаталогВременныхФайлов() + "dynamic_packet.pdf";
ПакетДокументов = Новый ПакетОтображаемыхДокументов;
// ... (заполнение пакета документами)
ПакетДокументов.ЗаписатьФайлДляПечати(ПутьКФайлуPDF);
// Формируем динамические параметры командной строки для утилиты pdfprint.exe
// -paper bin 1 для первого диапазона страниц, -paper bin 2 для второго
// -staple 1 активирует степлер для всего задания
ИмяПринтера = "RICOH SP 8400DN";
ШаблонКоманды = "pdfprint.exe -printer """ + ИмяПринтера + """ -staple 1 ";
ПараметрыСтраниц = "-prompts -binpages 1-" + Строка(СтраницВПервомДокументе) + "=1,"
+ Строка(СтраницВПервомДокументе + 1) + "-"
+ Строка(СтраницВПервомДокументе + СтраницВоВторомДокументе) + "=2 ";
ПолнаяКоманда = ШаблонКоманды + ПараметрыСтраниц + """" + ПутьКФайлуPDF + """";
// Выполняем отправку задания
ЗапуститьПриложение(ПолнаяКоманда, , Истина);
При таком подходе внешняя утилита генерирует единый поток данных печати (обычно в формате PostScript или PCL), внутри которого прописывает команды переключения лотков принтера непосредственно перед выводом соответствующих страниц. Для принтера это выглядит как единое неделимое задание, и финишер-степлер срабатывает корректно для всего набора документов.
---
Это наиболее гибкий и продвинутый метод, который используется в крупных высоконагруженных системах (например, на крупных складах или в архивах). Он позволяет полностью контролировать печать любого оборудования без привязки к интерфейсу драйвера Windows.
Суть метода заключается в том, что мы конвертируем полученный из 1С PDF-файл в текстовый формат описания страниц PostScript (PS) с помощью бесплатной библиотеки Ghostscript. После этого мы можем программно модифицировать полученный текстовый файл, внедряя в него стандартные управляющие команды принтера (PJL и PS-операторы), и отправить готовый файл напрямую в сетевой порт принтера.
Выясним подробнее, как выглядит алгоритм реализации этого метода:
pdf2ps (входит в состав Ghostscript), конвертируем PDF в PostScript-файл:
pdf2ps.exe input.pdf output.ps
output.ps в 1С как текстовый файл и внедряем команды управления лотками и финишером. В языке PostScript за выбор лотка отвечает оператор setpagedevice.
%%BeginPageSetup
[{
/MediaPosition 1 % Номер лотка на принтере (0 - авто, 1 - лоток 1, 2 - лоток 2)
} setpagedevice] ПодготовитьСтраницу
%%EndPageSetup
<</Staple 3 /StapleDetails <</Type 1 /StaplePosition /UpperLeft>> >> setpagedevice
// Пример отправки "сырых" данных (RAW) на принтер через TCP-сокет
Сокет = Новый TCPСоединение("192.168.1.100", 9100);
ЗаписьДанных = Новый ЗаписьДанных(Сокет.ПолучитьПотокВывода());
// Читаем подготовленный PostScript файл с командами управления
ТекстPS = Новый ТекстовыйДокумент;
ТекстPS.Прочитать(ПутьКМодифицированномуФайлуPS, КодировкаТекста.ANSI);
// Отправляем поток байтов принтеру
ЗаписьДанных.ЗаписатьСтроку(ТекстPS.ПолучитьТекст());
ЗаписьДанных.СброситьБуфер();
Сокет.Закрыть();
Этот метод гарантирует 100% стабильность работы и независимость от драйверов операционной системы Windows. Он позволяет на лету комбинировать любые лотки, типы бумаги, двухстороннюю печать и режимы сшивания на профессиональных МФУ RICOH.
---
Выбор оптимального метода зависит от вашей инфраструктуры и версии платформы: