Как программно свернуть определенные группировки в отчете СКД по условию

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с Системой компоновки данных (СКД) разработчики часто сталкиваются с ограничением: стандартные настройки позволяют либо полностью развернуть все группировки, либо свернуть их до определенного уровня. Однако в реальных задачах часто требуется гибкость. Например, если в отчете есть группировка по статьям бюджета, мы можем захотеть автоматически развернуть только ветку "Доходы", а ветку "Расходы" оставить свернутой для удобства пользователя.

В этой статье мы подробно разберем, как реализовать условное управление видимостью и состоянием группировок программными методами 1С.

Почему стандартных настроек СКД недостаточно?

На вкладке "Настройки" в схеме компоновки данных можно управлять параметром "Тип вывода группы" или использовать настройки в автополе, но эти параметры применяются ко всем данным этой группировки. СКД не знает о содержимом данных в момент применения статических настроек. Чтобы воздействовать на конкретную ветку дерева (например, свернуть только те строки, где значение не равно определенному тексту), нам придется вмешаться в процесс формирования отчета.

Способ 1: Перехват процесса вывода в процедуре ПриКомпоновкеРезультата

Это наиболее правильный и эффективный метод с точки зрения производительности. Мы не будем дожидаться полного формирования документа, а будем анализировать данные в процессе их вывода. Для этого нам нужно открыть модуль объекта отчета и найти (или создать) процедуру ПриКомпоновкеРезультата.

Рассмотрим по шагам, как это реализовать:

  1. Отключаем стандартную обработку формирования отчета, чтобы взять управление в свои руки.
  2. Инициализируем все необходимые объекты: КомпоновщикМакета, ПроцессорКомпоновки и ПроцессорВывода.
  3. В цикле получаем каждый элемент результата компоновки.
  4. Анализируем значения полей в текущем элементе.
  5. Выводим элемент в табличный документ и, если условие выполняется, применяем методы сворачивания.

Проанализируем пример кода для этого метода:


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

Способ 2: Постобработка сформированного Табличного Документа

Если вам кажется сложным переписывать весь процесс вывода, можно воспользоваться методом "обхода" уже готового табличного документа. Выясним причину, почему это иногда удобнее: в готовом документе у нас есть доступ к свойству Расшифровка каждой ячейки, что позволяет точно определить, какие данные находятся в строке.

Разберем алгоритм обхода:

  1. Дожидаемся формирования отчета (код пишется в конце ПриКомпоновкеРезультата после вызова СтандартнаяОбработка = Истина, но лучше все же делать это при СтандартнаяОбработка = Ложь после ручного вывода).
  2. Циклом проходим по всем строкам ТабличныйДокумент.
  3. Проверяем уровень группировки строки с помощью метода УровеньГруппировки().
  4. Если это нужный нам уровень, проверяем значение в ячейке или в данных расшифровки.
  5. Если значение не равно "Доходы", используем метод ПоказатьУровеньГруппировокСтрок() или СвернутьГруппировку().

Посмотрим на пример реализации обхода:


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

Важные методы и свойства для работы с группировками

Для успешной реализации задачи крайне важно понимать разницу между основными инструментами управления строками:

Рекомендации по оптимизации

Рассмотрим несколько практических советов, которые помогут сделать отчет быстрее и стабильнее:

1. Использование именованных областей: Если вы создаете собственный макет для группировок в СКД, назначьте им имена. В коде 1С гораздо проще найти строку через ДокументРезультат.НайтиТекст() или по имени области, чем перебирать тысячи строк в цикле.

2. Определение границ группировки: Помните, что при сворачивании программно важно знать, где группа начинается и где заканчивается. Если вы используете метод ПоказатьУровеньГруппировокСтрок, вам нужно передать в него весь диапазон строк, входящих в данную ветку. Определить конец ветки можно, найдя следующую строку с таким же или более высоким уровнем иерархии.

3. Интерактивность: Если задача стоит так, чтобы пользователь мог "одной кнопкой" свернуть все лишнее, лучше вынести этот код в отдельную команду на форме отчета. Это позволит пользователю сначала увидеть полный отчет, а затем применить фильтр визуализации.

Проанализировав все способы, можно сделать вывод: наиболее гибким является Способ 1 с ручным перебором элементов процессора компоновки, так как он дает полный контроль над данными еще до того, как они будут отрисованы на экране. Однако для простых отчетов с жесткой структурой вполне подойдет и Способ 2 с постобработкой табличного документа.

← На главную