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