Как распечатать несколько выделенных документов в одно окно в 1С?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При автоматизации ежедневной работы пользователей в 1С часто возникает задача пакетной печати: бухгалтер или менеджер выделяет в журнале или форме списка несколько документов и отправляет их на принтер либо открывает для предварительного просмотра. Однако стандартный обход выделенных строк в цикле с вызовом типовых процедур формирования печатных форм приводит к тому, что система открывает отдельное окно предварительного просмотра для каждого документа. Разберем, почему возникает такое поведение и как правильно объединить печать в один общий табличный документ.

Выясним причину исходной проблемы

Проанализируем типовой код, который разработчики часто пытаются применить в форме списка документов (например, в конфигурации «Управление производственным предприятием»):


Процедура ДействияФормыДействиеПечатьВД(Кнопка)
    Если ЭтаФорма.ЭлементыФормы.Список.ТекущаяСтрока = Неопределено Тогда 
        Возврат;
    КонецЕсли;

    Для Каждого ДокументСсылка Из ЭтаФорма.ЭлементыФормы.Список.ВыделенныеСтроки Цикл
        УниверсальныеМеханизмы.НапечататьДокументИзФормыСписка(ДокументСсылка.ПолучитьОбъект());
    КонецЦикла;
КонецПроцедуры

Процедура УниверсальныеМеханизмы.НапечататьДокументИзФормыСписка внутри себя обращается к функции печати конкретного объекта, получает готовый макет и сразу же открывает общую форму предпросмотра ОбщиеФормы.ПечатьДокументов. При итерации по списку выделенных строк на каждом шаге цикла инициируется отдельный диалог показа. В результате рабочий стол пользователя заполняется десятками открытых окон.

Чтобы избежать открытия множества окон, необходимо придерживаться другого принципа: собрать все макеты в один результирующий ТабличныйДокумент, разделить их горизонтальными разделителями страниц и только затем передать сформированный результат в форму отображения.

Реализация пакетной печати в обычных формах (УПП, толстый клиент)

Разберем по шагам правильный алгоритм групповой печати на форме списка документов в толстом клиенте:

  1. Перед циклом создадим один общий экземпляр объекта ТабличныйДокумент.
  2. Обойдем массив ВыделенныеСтроки табличного поля списка.
  3. Для каждого документа вызовем функцию печати, возвращающую макет (без вызова процедур немедленного отображения).
  4. Присоединим полученный документ к общему с помощью метода Вывести().
  5. Между документами добавим горизонтальный разделитель страниц с помощью метода ВывестиГоризонтальныйРазделительСтраниц(). Важно не ставить разделитель после самого последнего документа, чтобы не печатать пустой лист.
  6. Вызовем универсальную процедуру УниверсальныеМеханизмы.НапечататьДокумент() для итогового табличного документа.

Посмотрим на пример программной реализации обработчика кнопки формы списка:


Процедура ДействияФормыПечатьПакета(Кнопка)
    
    ВыделенныеСтроки = ЭтаФорма.ЭлементыФормы.Список.ВыделенныеСтроки;
    КоличествоДокументов = ВыделенныеСтроки.Количество();
    
    Если КоличествоДокументов = 0 Тогда
        Возврат;
    КонецЕсли;
    
    ТабДокИтоговый = Новый ТабличныйДокумент;
    Индекс = 0;
    
    Для Каждого Ссылка Из ВыделенныеСтроки Цикл
        Индекс = Индекс + 1;
        
        ДокОбъект = Ссылка.ПолучитьОбъект();
        // Вызываем функцию печати, формирующую печатную форму
        ТабДокТекущий = ДокОбъект.Печать("СчетЗаказ");
        
        Если ТабДокТекущий <> Неопределено Тогда
            ТабДокИтоговый.Вывести(ТабДокТекущий);
            
            // Добавляем разделитель страниц между документами
            Если Индекс < КоличествоДокументов Тогда
                ТабДокИтоговый.ВывестиГоризонтальныйРазделительСтраниц();
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    
    Если ТабДокИтоговый.ВысотаТаблицы > 0 Тогда
        // Открываем единую форму предварительного просмотра УПП
        УниверсальныеМеханизмы.НапечататьДокумент(ТабДокИтоговый, 1, , "Групповая печать");
    КонецЕсли;
    
КонецПроцедуры

Особенности пакетной печати в конфигурациях на базе БСП

Если конфигурация разработана с использованием Библиотеки стандартных подсистем (БСП) на управляемых формах, механизм пакетного вывода реализован разработчиками платформы штатно. Подсистема «Управление печатью» принимает в команду не одну ссылку, а целый массив объектов печати.

Рассмотрим, как выглядит вызов команды печати на клиенте:


&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
    // ПараметрКоманды автоматически содержит массив ссылок на выделенные строки
    УправлениеПечатьюКлиент.ВыполнитьКомандуПечати(
        "Документ.ЗаказПокупателя", 
        "СчетЗаказ", 
        ПараметрКоманды, 
        ПараметрыВыполненияКоманды.Источник
    );
КонецПроцедуры

В модуле менеджера объекта процедура печати принимает массив документов и формирует общий табличный документ для всей переданной коллекции:


Процедура Печать(МассивОбъектов, ПараметрыПечати, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
    
    Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "СчетЗаказ") Тогда
        ТабДок = СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати);
        УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
            КоллекцияПечатныхФорм, 
            "СчетЗаказ", 
            "Счет на оплату", 
            ТабДок
        );
    КонецЕсли;
    
КонецПроцедуры

Важные технические нюансы и ограничения

Проанализируем технические детали, которые необходимо учитывать при объединении макетов:

  1. Параметры страницы: метод ВывестиГоризонтальныйРазделительСтраниц() делит макет на страницы для печатающего устройства, однако свойства страницы (такие как ОриентацияСтраницы, АвтоМасштаб, поля документа) задаются для всего объекта ТабличныйДокумент в целом. Если объединяются документы с разной ориентацией (например, альбомная накладная и книжное приложение), итоговый документ примет единые параметры (как правило, первого выведенного макета).
  2. Подключаемые внешние печатные формы (ВПФ) в обычных формах: стандартная подсистема регистрации внешних печатных форм в не-БСП конфигурациях (УПП 1.3, УТ 10.3) передает в реквизит внешней обработки СсылкаНаОбъект строго одну ссылку. Пакетная печать из выделенных строк типовым механизмом ВПФ не предусмотрена — обработка будет вызываться поочередно для каждого объекта. Для массовой печати в таких системах решение оформляют либо в виде доработки формы журнала документов, либо в виде отдельной сервисной обработки с табличной частью для подбора документов.
  3. Производительность: метод Ссылка.ПолучитьОбъект() считывает из базы данных всю структуру объекта со всеми табличными частями. Если планируется массовая печать сотен документов за один раз, вызовы ПолучитьОбъект() в цикле создадут повышенную нагрузку на сервер СУБД и память клиентского приложения. В высоконагруженных сценариях предпочтительно получать все данные для печати одним запросом по всему массиву ссылок.
← На главную