Как программно сформировать структуру группировок в СКД

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

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

Особенности программного управления структурой СКД

Прежде чем приступать к коду, выясним ключевые принципы работы со структурой компоновки данных:

  1. Коллекция Структура объекта НастройкиКомпоновкиДанных хранит корневые элементы отчета (группировки, таблицы, диаграммы).
  2. Чтобы создать иерархическое дерево (когда каждая последующая группировка вложена в предыдущую), новый элемент ГруппировкаКомпоновкиДанных добавляется не в корневую структуру, а в коллекцию Структура родительской группировки.
  3. Если в наборе данных уже выбрана ссылка (например, Номенклатура), нет необходимости динамически дописывать SQL-запрос для извлечения ее реквизитов. СКД умеет автоматически разыменовывать поля через точку (например, Номенклатура.Артикул). Достаточно передать этот путь в объект ПолеКомпоновкиДанных.
  4. Коллекция ПоляГруппировки отвечает за то, по какому именно полю схлопываются данные, а коллекция Выбор — за то, какие поля отображаются в строке этой группировки.

Пошаговое создание вложенной структуры группировок

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

Разберем пример реализации на сервере:


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

Явное указание выводимых полей в детальных записях

Если в детальных записях требуется вывести строго определенный набор полей, а не автовыбор, заменим элемент АвтоВыбранноеПолеКомпоновкиДанных на конкретные элементы ВыбранноеПолеКомпоновкиДанных. Посмотрим на фрагмент кода:


ДетальныеЗаписи = УровеньГруппировки.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
ДетальныеЗаписи.Имя = "ДетальныеЗаписи";
ДетальныеЗаписи.Использование = Истина;

// Добавляем конкретные колонки
ПолеНоменклатура = ДетальныеЗаписи.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
ПолеНоменклатура.Поле = Новый ПолеКомпоновкиДанных("Номенклатура");
ПолеНоменклатура.Использование = Истина;

ПолеОстаток = ДетальныеЗаписи.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
ПолеОстаток.Поле = Новый ПолеКомпоновкиДанных("КоличествоОстаток");
ПолеОстаток.Использование = Истина;

Программный вывод отчета в Табличный документ

После того как структура сформирована, запустим стандартный конвейер вывода отчета СКД в табличный документ без использования стандартных команд формы:


&НаСервере
Процедура СформироватьИВывестиОтчет(ТабличныйДокумент)
    
    Схема = Отчет.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
    Настройки = Отчет.КомпоновщикНастроек.ПолучитьНастройки();
    
    ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    
    МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки, ДанныеРасшифровки);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
    
    ТабличныйДокумент.Очистить();
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ТабличныйДокумент);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
КонецПроцедуры

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

  1. Пользовательские настройки: При динамическом перестроении структуры очищайте коллекцию КомпоновщикНастроек.ПользовательскиеНастройки.Элементы, чтобы сохраненные пользовательские варианты не перекрывали программные изменения.
  2. Использование функционала БСП: Если в конфигурации используется «Библиотека стандартных подсистем», для упрощения работы с группировками можно использовать методы общего модуля КомпоновкаДанныхКлиентСервер, например, процедуру КомпоновкаДанныхКлиентСервер.ДобавитьГруппировку().
← На главную