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