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