Как в отчете на СКД не выводить верхний уровень иерархии?

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

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

Если мы попробуем решить эту задачу прямым способом — добавив в отбор группировки условие вида СистемныеПоля.Уровень > 1, то отчет вернется полностью пустым. Выясним причину такого поведения: в стандартном механизме иерархии СКД дочерние узлы жестко привязаны к родительским. Отсекая корневой узел первого уровня, платформа автоматически исключает всю подчиненную ветвь. Отдельной стандартной настройки для отключения только первого уровня в СКД не предусмотрено. Рассмотрим подробнее рабочие способы решения этой задачи.

Способ 1. Настройка собственной иерархии через связи наборов данных

Наиболее универсальный и гибкий подход — использование механизма собственной иерархии. Разберем по шагам, как настроить такую схему компоновки:

  1. В схеме компоновки данных создадим два набора данных или используем связь одного набора данных «сам на себя».
  2. В основном наборе данных получаем список элементов и групп, начиная со второго уровня (где поле Родитель заполнено, либо исключая корневые элементы через условие запроса).
  3. Перейдем на вкладку Связи наборов данных и настроим иерархическую связь.
  4. В качестве источника и приемника связи укажем наш набор данных, установим поле связи (например, Ссылка и Родитель) и отметим признак Иерархия.
  5. В колонке Выражение начального значения и в параметрах связи ограничим выборку так, чтобы построение дерева начиналось со второго уровня иерархии.

Таким образом, для СКД вершинами дерева станут узлы второго уровня, а корневые группы верхнего уровня в результат компоновки вообще не попадут.

Способ 2. Сдвиг родителя в запросе набора данных

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

  1. В запросе проверяем, принадлежит ли непосредственный родитель текущей записи к самому первому уровню.
  2. Если родитель находится на 1-м уровне, подменяем его значение на пустую ссылку (или NULL).
  3. Для остальных уровней оставляем исходное значение поля Родитель.

Посмотрим на пример фрагмента запроса:


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка,
    ВЫБОР
        КОГДА Номенклатура.Родитель.Родитель = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
            ТОГДА ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
        ИНАЧЕ Номенклатура.Родитель
    КОНЕЦ КАК РодительДляИерархии,
    Номенклатура.Наименование КАК Наименование
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Родитель <> ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)

Связав такой набор данных по полю РодительДляИерархии, мы получим дерево без верхнего уровня.

Способ 3. Использование пользовательских полей и выражений СКД

Если мы не хотим менять исходный запрос, настроим логику на уровне схемы компоновки данных:

  1. На вкладке Пользовательские поля создадим новое поле-выражение.
  2. Зададим расчетное выражение с проверкой уровня через функции СКД:
    
    Выбор Когда Уровень() = 0 Тогда Неопределено Иначе ВычислитьВыражение("Ссылка", , "Иерархия") Конец
    
  3. В настройках структуры отчета для группировки установим отбор с типом применения После группировки или для иерархии, исключающий корневой узел без потери вложенных элементов.

Способ 4. Программный вывод результата компоновки

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

Разберем по шагам логику вывода в табличный документ:


ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);

ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(Результат);

ПроцессорВывода.НачатьВывод();

Пока Истина Цикл
    ЭлементРезультата = ПроцессорКомпоновки.Следующий();
    Если ЭлементРезультата = Неопределено Тогда
        Прервать;
    КонецЕсли;
    
    // Пропускаем вывод строки верхнего уровня иерархии
    Если ЭлементРезультата.Уровень = 1 И ЭлементРезультата.ТипЭлемента = ТипЭлементаРезультатаКомпоновкиДанных.Группировка Тогда
        Продолжить;
    КонецЕсли;
    
    ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
КонецЦикла;

ПроцессорВывода.ЗакончитьВывод();

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

← На главную