В процессе работы с отчетами на Системе Компоновки Данных (СКД) часто возникает задача сделать их более удобными для анализа. Одна из таких задач — создание сворачиваемых групп колонок, аналогично тому, как это реализовано в Microsoft Excel. Это позволяет пользователю скрывать детализацию и видеть только обобщенные данные, а при необходимости — разворачивать группы для просмотра подробной информации.
Рассмотрим ситуацию: у нас есть готовый отчет, сформированный СКД, и нам нужно программно, уже после вывода результата, добавить группировку для нескольких колонок. Стандартная попытка использовать метод Сгруппировать() для всего табличного документа часто приводит к неожиданному результату — группируется не область данных, а какая-то посторонняя строка, например, заголовок отчета. Проанализируем, почему так происходит и как правильно решить эту задачу.
Ключ к пониманию проблемы лежит в структуре объекта ТабличныйДокумент, который формирует СКД. Такой документ — не просто единая сетка. Он может состоять из нескольких областей, каждая со своим собственным форматированием, в частности, с разной шириной колонок. Это называется "формат строк". Например, заголовок отчета, шапка таблицы и строки с данными могут иметь разное форматирование.
Когда мы вызываем метод ДокументРезультат.Сгруппировать() без указания конкретной области, он применяется к формату строк, который активен в самом начале документа. Чаще всего это область заголовка, которая состоит из одной объединенной ячейки. В результате группировка применяется к ней, а не к таблице с данными, как мы ожидаем.
Чтобы группировка сработала корректно, нам нужно явно указать, к какой именно прямоугольной области табличного документа ее следует применить.
Этот способ основан на постобработке уже сформированного отчета в процедуре ПриКомпоновкеРезультата(). Суть метода — получить нужную область с помощью метода Область() и уже к ней применить Сгруппировать().
Синтаксис метода выглядит так:
ТабличныйДокумент.Область(НомерПервойСтроки, НомерПервойКолонки, НомерПоследнейСтроки, НомерПоследнейКолонки)
Для нашей задачи нужно определить номера колонок, которые мы хотим сгруппировать, а также указать диапазон строк, на который эта группировка должна распространяться. Важно захватить все строки отчета, включая шапку и данные.
Посмотрим на пример кода в обработчике ПриКомпоновкеРезультата:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Истина; // Выполняем стандартное формирование отчета
// После того как отчет сформирован, ДокументРезультат заполнен.
// Теперь мы можем его доработать.
// Предположим, мы хотим сгруппировать колонки с 5-й по 7-ю.
НомерПервойКолонкиДляГруппировки = 5;
НомерПоследнейКолонкиДляГруппировки = 7;
// Определяем, на какие строки будет действовать группировка.
// Нам нужно начать с первой строки (или со строки шапки) и закончить последней.
// Если этого не сделать, группировка может примениться только к одной строке.
НомерПервойСтроки = 1;
НомерПоследнейСтроки = ДокументРезультат.ВысотаТаблицы;
// Получаем нужную область и применяем метод Сгруппировать()
// Параметр Истина означает, что группируются именно колонки.
ОбластьДляГруппировки = ДокументРезультат.Область(
НомерПервойСтроки,
НомерПервойКолонкиДляГруппировки,
НомерПоследнейСтроки,
НомерПоследнейКолонкиДляГруппировки
);
ОбластьДляГруппировки.Сгруппировать(Истина);
КонецПроцедуры
Важный момент: основная ошибка, с которой столкнулся автор в теме на форуме, заключалась в том, что не был указан полный диапазон строк. Если вызвать метод, например, так: ДокументРезультат.Область(, 5, , 7), то платформа может взять только первую строку. Указание последней строки (НомерПоследнейСтроки) решает эту проблему и применяет группировку ко всей высоте таблицы.
Этот метод хорош, когда структура отчета заранее известна или ее можно легко вычислить. Однако в сложных динамических отчетах определение номеров нужных колонок и строк может стать нетривиальной задачей.
В большинстве случаев можно обойтись без программирования. СКД предоставляет мощные инструменты для настройки структуры отчета, включая вложенные группировки колонок. Это наиболее правильный и предпочтительный способ, так как все настройки хранятся в варианте отчета и могут легко изменяться пользователем.
Разберем по шагам, как это сделать:
После формирования отчета вы увидите, что над вашими колонками появилась общая шапка, а слева от нее — значок "+" или "-", позволяющий сворачивать и разворачивать эту группу. Этот подход не требует ни строчки кода и является более гибким.
Этот метод полезен в тех редких случаях, когда вы формируете табличный документ полностью вручную, без использования стандартного вывода СКД, например, последовательно присоединяя области макета.
У объекта ТабличныйДокумент есть пара методов:
НачатьАвтогруппировкуКолонок()ЗакончитьАвтогруппировкуКолонок()Все колонки, которые будут выведены в табличный документ между вызовами этих двух методов, будут автоматически объединены в одну группу.
Посмотрим на пример:
Процедура СформироватьОтчет(ТабДок)
Макет = ПолучитьМакет("МойМакет");
ОбластьКолонка1 = Макет.ПолучитьОбласть("Колонка1");
ОбластьКолонка2 = Макет.ПолучитьОбласть("Колонка2");
ОбластьКолонка3 = Макет.ПолучитьОбласть("Колонка3");
// ... код вывода заголовков и прочих областей ...
// Начинаем создавать группу
ТабДок.НачатьАвтогруппировкуКолонок();
// Выводим колонки, которые должны попасть в группу
ТабДок.Присоединить(ОбластьКолонка1);
ТабДок.Присоединить(ОбластьКолонка2);
// Завершаем создание группы
ТабДок.ЗакончитьАвтогруппировкуКолонок();
// Эта колонка уже не попадет в группу
ТабДок.Присоединить(ОбластьКолонка3);
// ...
КонецПроцедуры
Этот способ менее универсален для доработки отчетов СКД, но незаменим при ручной сборке сложных табличных документов.
Подведем итог. Хотя программная доработка готового отчета и является рабочим решением, в первую очередь всегда стоит попытаться настроить группировки стандартными средствами конструктора СКД. Это проще, быстрее и позволяет пользователям самостоятельно кастомизировать отчеты. Программный подход оправдан лишь в тех случаях, когда требуется сложная логика группировки, недостижимая декларативными настройками.