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