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

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

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

Разберем основные причины сложности такой задачи и подробно рассмотрим практические способы ее реализации в СКД.

Особенности работы с иерархией в платформе 1С

Перед реализацией отчета проанализируем ограничения и особенности структуры данных 1С:

  1. Хранение связей «снизу вверх»: Каждый элемент справочника содержит ссылку только на своего непосредственного родителя (поле Родитель). Прямое обращение через точку вида Номенклатура.Родитель.Родитель возвращает предков относительно текущего элемента, а не от корня дерева. Если в справочнике элементы имеют разную глубину вложенности, такое обращение приведет к смещению уровней.
  2. Отсутствие автоматического горизонтального разворота: СКД не имеет встроенной настройки для динамического разбиения произвольного дерева на неизвестное заранее число колонок. Поэтому число отображаемых колонок-уровней обычно фиксируют или формируют программно.

Способ 1. Вычисление абсолютных уровней иерархии в запросе СКД

Если максимальная глубина вложенности справочника заранее известна и ограничена (например, до 3 уровней), наиболее производительным и надежным решением является вычисление абсолютных уровней иерархии непосредственно в тексте запроса с помощью условий ВЫБОР КОГДА.

Рассмотрим пример запроса, в котором определяются родительские группы абсолютных уровней 1, 2 и 3 для справочника Номенклатура:


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

В этом запросе мы определяем положение текущего элемента относительно корня справочника. Полученные поля Уровень1, Уровень2 и Уровень3 содержат ссылки на соответствующие группы от самого верхнего уровня к нижнему.

Способ 2. Использование вычисляемых полей и функций общего модуля

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

Для этого в общем серверном модуле создадим экспортную функцию, которая по ссылке определяет родителя заданного абсолютного уровня:


Функция ПолучитьРодителяУровня(Ссылка, НомерУровня) Экспорт
    
    Если Не ЗначениеЗаполнено(Ссылка) Тогда
        Возврат Справочники.Номенклатура.ПустаяСсылка();
    КонецЕсли;
    
    МассивРодителей = Новый Массив;
    ТекущийЭлемент = Ссылка;
    
    Пока ЗначениеЗаполнено(ТекущийЭлемент) Цикл
        МассивРодителей.Вставить(0, ТекущийЭлемент);
        ТекущийЭлемент = ТекущийЭлемент.Родитель;
    КонецЦикла;
    
    Индекс = НомерУровня - 1;
    Если Индекс < МассивРодителей.Количество() Тогда
        Возврат МассивРодителей[Индекс];
    Иначе
        Возврат Справочники.Номенклатура.ПустаяСсылка();
    КонецЕсли;
    
КонецФункции

Затем на вкладке Вычисляемые поля в СКД добавим поля Уровень1, Уровень2, Уровень3 и пропишем выражения для их вычисления:

  1. Для поля Уровень1: ИмяМодуля.ПолучитьРодителяУровня(Номенклатура, 1)
  2. Для поля Уровень2: ИмяМодуля.ПолучитьРодителяУровня(Номенклатура, 2)
  3. Для поля Уровень3: ИмяМодуля.ПолучитьРодителяУровня(Номенклатура, 3)

Способ 3. Программная подготовка данных через внешний набор данных

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

Настройка структуры отчета для горизонтального вывода

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

  1. Перейдем на вкладку Настройки схемы компоновки данных.
  2. В структуру отчета добавим последовательные вложенные группировки строк: Уровень1 > Уровень2 > Уровень3 > Номенклатура (или детальные записи).
  3. Для каждой группировки установим тип группировки: Без иерархии, так как иерархическая вложенность уже реализована через отдельные поля.
  4. В свойствах отчета в блоке Другие настройки найдем параметр Расположение полей группировок и установим для него значение Отдельно или Отдельно и только в итогах. Это ключевая настройка, которая исключает смещение колонок «лесенкой» и выводит каждый уровень строго в своей отдельной колонке.
  5. В список выбранных полей выведем необходимые ресурсы.

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

← На главную