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