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