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