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