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