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