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