Как организовать массовую печать документов из отчета СКД в 1С?

Программист 1С v8.3 (Управляемые формы) 1С:Управление нашей фирмой Управленческий учет Торговля и дистрибуция
← На главную

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

Основная проблема делится на две части:

  1. Как программно получить массив ссылок на документы из уже сформированного отчета на СКД?
  2. Как передать этот массив в механизм печати, управляя при этом выбором печатной формы?

Проанализируем доступные методы и приведем примеры кода для их реализации.

Способы получения данных из отчета СКД

Чтобы запустить печать, нам сначала нужен список объектов для печати. Если этот список формируется отчетом, у нас есть два основных пути, чтобы его "извлечь".

Способ 1: Анализ данных расшифровки

Этот способ подходит для интерактивных сценариев, когда пользователь уже видит сформированный отчет на экране и нажимает на нем кнопку "Печать". Каждая ячейка в табличном документе отчета СКД может содержать данные расшифровки, которые хранят информацию об исходных данных, использованных для ее формирования, включая ссылки на документы.

Алгоритм действий:

  1. Получить доступ к данным расшифровки табличного документа, в который выведен отчет.
  2. Обойти элементы расшифровки в цикле.
  3. Найти поля, содержащие нужный тип данных (например, СправочникСсылка.Контрагенты или ДокументСсылка.ЗаказПокупателя).
  4. Собрать найденные ссылки в массив, исключая дубликаты.

Посмотрим на пример функции, которая обходит расшифровку и собирает массив уникальных контрагентов. Аналогичный подход можно использовать и для сбора документов.


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

// Пример вызова для получения документов "ЗаказПокупателя"
// Предполагается, что "Результат" - это ТабличныйДокумент с отчетом
// и "ДанныеРасшифровки" - его данные расшифровки
МассивДокументов = ПолучитьМассивОбъектовИзРасшифровки(ДанныеРасшифровки, "Регистратор", Тип("ДокументСсылка.ЗаказПокупателя"));

Важный нюанс: чтобы этот метод сработал, в настройках отчета СКД для поля с документом должна быть включена расшифровка.

Способ 2: Программное формирование отчета в ТаблицуЗначений

Этот метод более надежен и не зависит от того, что видит пользователь на экране. Суть в том, чтобы выполнить компоновку данных "в фоне", но не в табличный документ, а сразу в коллекцию данных, например, в ТаблицуЗначений.

Алгоритм действий:

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

Этот подход более сложен в реализации, но дает полный контроль над получаемыми данными. Он идеален, если печать запускается не из формы отчета, а, например, из отдельной обработки.

Организация массовой печати документов

Итак, мы получили массив ссылок на документы. Теперь нужно отправить их на печать. В современных конфигурациях на базе Библиотеки стандартных подсистем (БСП) для этого есть удобный механизм.

Использование УправлениеПечатьюКлиент

Для вызова стандартных команд печати используется общий модуль УправлениеПечатьюКлиент и его процедура ВыполнитьКомандуПечати. Она берет на себя всю работу по формированию и отображению печатных форм.

Рассмотрим пример кода для массовой печати документов ЗаказПокупателя, массив которых уже собран.


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

КонецПроцедуры

Этот код отправит все документы из массива МасДок на печать с использованием печатной формы "ЗаказПокупателя".

Выбор печатной формы в зависимости от контрагента

Теперь решим главную задачу — печать разных форм для разных клиентов.

  1. Группируем документы. После получения общего массива документов из отчета, его нужно сгруппировать по контрагентам и требуемым печатным формам. Для этого можно использовать Соответствие или ТаблицуЗначений.
  2. Определяем форму печати. Логику определения нужной формы можно хранить где угодно: в дополнительном реквизите справочника "Контрагенты", в отдельном регистре сведений ("Печатные формы для контрагентов") и т.д.
  3. Печатаем в цикле. Обходим сгруппированные данные и для каждой группы (один контрагент/одна форма печати) вызываем УправлениеПечатьюКлиент.ВыполнитьКомандуПечати со своим массивом документов и своим идентификатором макета.

Особые случаи и параметры

Печать Универсального передаточного документа (УПД)

Печать УПД часто связана не с документом реализации, а с документом Счет-фактура выданный. Поэтому для массовой печати УПД алгоритм будет немного другим:

  1. Собрать массив документов-оснований (например, "Реализация товаров и услуг").
  2. Для каждого документа-основания найти или создать на его основании Счет-фактуру выданный.
  3. Собрать массив ссылок на эти счета-фактуры.
  4. Вызвать команду печати УПД, передав ей массив счетов-фактур. Менеджером печати и идентификатором макета будет что-то вроде Обработка.ПечатьСчетФактура.УниверсальныйПередаточныйДокумент. Точное имя нужно смотреть в конфигураторе для вашей версии программы.

Передача количества экземпляров

Иногда нужно указать, сколько копий документа печатать. Для этого используется структура ДополнительныеПараметрыПечати. Стандартное имя параметра — КоличествоЭкземпляров.


// ...
ДополнительныеПараметрыПечати = Новый Структура();
ДополнительныеПараметрыПечати.Вставить("КоличествоЭкземпляров", 2); // Задаем 2 экземпляра

ПараметрыПечати = Новый Структура("ЗаголовокФормы,Идентификатор,ДополнительныеПараметры",
                                 "Печать накладных",
                                 "Накладная",
                                 ДополнительныеПараметрыПечати);
// ...

Важно: если этот параметр не срабатывает, это означает, что конкретная команда печати или макет в вашей конфигурации не обрабатывают его. В этом случае необходимо открыть в конфигураторе модуль менеджера печати соответствующего объекта (например, Документ.ЗаказПокупателя) и найти процедуру Печать(). В ней можно увидеть, какие именно дополнительные параметры она ожидает и как их использует.

← На главную