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