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