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