Как изменить запрос и управлять уровнями иерархии в СКД после компоновки макета

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

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

Процесс формирования макета и перехват запроса

Для начала проанализируем, как СКД готовит данные к выводу. Когда мы нажимаем кнопку «Сформировать», система проходит несколько этапов: инициализация схемы, настройка компоновщика и, наконец, компоновка макета. Именно на этапе создания МакетКомпоновкиДанных формируется итоговый текст запроса, который может существенно отличаться от того, что вы написали в конструкторе на закладке «Наборы данных».

Если в настройках отчета выбрана группировка по иерархии, СКД автоматически достраивает запрос, чтобы получить родительские записи. Рассмотрим, как мы можем программно получить доступ к этому тексту и изменить его. Для этого нам понадобится объект КомпоновщикМакетаКомпоновкиДанных.

Выполним следующие шаги в модуле отчета или обработки:


// Сначала создаем компоновщик макета
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

// Компонуем макет, передавая схему и настройки
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки());

// Теперь мы можем обратиться к наборам данных макета
Для Каждого НаборДанных Из МакетКомпоновки.НаборыДанных Цикл
    Если ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Тогда
        // Здесь находится итоговый текст запроса
        ТекстЗапроса = НаборДанных.Запрос;
        
        // Пример замены текста:
        НаборДанных.Запрос = СтрЗаменить(ТекстЗапроса, "СтароеУсловие", "НовоеУсловие");
    КонецЕсли;
КонецЦикла;

Важно понимать: если СКД генерирует запрос для иерархии, в коллекции НаборыДанных макета может появиться несколько элементов. Проанализируем ситуацию, когда нам нужно подменить конкретную часть логики выборки родителей. Это делается путем поиска нужного фрагмента текста в свойстве Запрос.

Управление уровнями иерархии без изменения запроса

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

Использование системного поля «Уровень»

Проанализируем ситуацию: в справочнике три уровня вложенности, и нам нужно вывести только 2-й и 3-й уровни. Вместо того чтобы мучительно править автогенерируемый запрос, мы можем воспользоваться встроенным функционалом отборов:

  1. Переходим на закладку Настройки в СКД.
  2. Выбираем вкладку Отбор.
  3. Добавляем новое поле. В списке доступных полей находим системное поле Уровень (оно доступно внутри группировки).
  4. Устанавливаем условие Больше 1.

Это автоматически отсечет корневые элементы на уровне движка компоновки. Если же нам нужно оставить данные для итогов, но скрыть их визуально, воспользуемся Условным оформлением.

Применение условного оформления для скрытия данных

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

  1. В настройках СКД переходим на вкладку Условное оформление.
  2. Добавляем новое оформление, где в качестве оформляемого поля выбираем наше иерархическое поле (например, Студент).
  3. В параметрах оформления устанавливаем Текст как пробел или пустую строку.
  4. В условии указываем: Уровень Равно 1.

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

Программное добавление вычисляемых полей

Иногда требуется добавить логику расчетов уже после того, как схема была создана, но до выполнения отчета. Вместо выгрузки результата в ТаблицуЗначений и ее последующей обработки, гораздо правильнее добавить Вычисляемое поле программно. Это позволит использовать агрегатные функции СКД и сохранить производительность.

Разберем, как это сделать программно через объект СхемаКомпоновкиДанных:


// Добавляем новое вычисляемое поле в схему
НовоеПоле = СхемаКомпоновкиДанных.ВычисляемыеПоля.Добавить();
НовоеПоле.ПутьКДанным = "КоличествоГрупп";
НовоеПоле.Выражение = "Выбор Когда Студент.ЭтоГруппа Тогда 1 Иначе 0 Конец";
НовоеПоле.Заголовок = "Количество групп";

// После модификации схемы важно обновить компоновщик настроек, 
// чтобы поле стало доступным для выбора
ИсточникДоступныхНастроек = Новый ОписаниеИсточникаДанныхКомпоновкиДанных(СхемаКомпоновкиДанных);
КомпоновщикНастроек.Инициализировать(ИсточникДоступныхНастроек);

Этот метод позволяет внедрять сложные расчеты (например, проверку уровней или условий по родителям) непосредственно в движок СКД.

Инструменты для отладки макета

Если вы столкнулись с тем, что «текста запроса нигде нет», как автор вопроса, настоятельно рекомендуем использовать специализированные инструменты. Одним из самых мощных являются Инструменты разработчика (ИР) и входящая в них Консоль СКД.

Выясним, чем она полезна:

  1. Просмотр итогового макета: Вы можете увидеть финальный XML-код макета, который генерирует система.
  2. Анализ временных таблиц: СКД часто создает временные таблицы для обработки иерархии. Консоль позволяет увидеть их структуру и содержимое.
  3. Отладка параметров: Вы увидите, какие именно значения параметров подставляются в реальный запрос к СУБД.

В завершение отметим, что прямое изменение текста запроса в макете — это крайняя мера. Проанализируйте возможность использования системных полей (Уровень, Родитель) и механизмов связей наборов данных (когда набор связывается сам с собой для построения иерархии). Это сделает ваш отчет более надежным и простым в поддержке.

← На главную