При разработке отчетов на базе Системы компоновки данных (СКД) в 1С программисты часто сталкиваются со стандартным поведением системы при выводе иерархических справочников (например, Номенклатура или Подразделения). По умолчанию СКД выводит иерархию в виде дерева («лесенкой» вниз). Это удобно для визуального восприятия на экране, но абсолютно непригодно, если пользователю нужно выгрузить данные в Excel для последующего анализа, построить плоскую таблицу или вывести каждый уровень в отдельную колонку (например: Склад | Папка 1-го уровня | Папка 2-го уровня | Товар).
Дополнительная сложность возникает, когда пользователю необходимо дать возможность самостоятельно выбирать в режиме «1С:Предприятие», какие именно уровни иерархии отображать в отчете. В этой статье мы подробно разберем четыре практических способа реализации этой задачи в СКД. Для решения подобных ситуаций можно воспользоваться готовым отчетом для получения и вывода родителей верхних уровней.
Малоизвестный, но крайне мощный механизм СКД — использование встроенных функций для работы с группировками. Для того чтобы обратиться к родительским записям иерархии и вытащить их на уровень детальных записей, мы можем использовать функцию ВычислитьВыражение с особыми параметрами.
Разберем по шагам, как настроить этот механизм:
Родитель1Уровня.
Выбор
Когда Уровень() > 0
Тогда ВычислитьВыражение("Ссылка", , "Иерархия")
Иначе Неопределено
Конец
Параметр "Иерархия" указывает СКД, что вычисление выражения должно происходить исключительно в контексте родительских записей текущей группировки. Это позволяет системе «подниматься» по дереву элементов вверх и возвращать значения вышестоящих уровней непосредственно в строку детальной записи элемента. Этот способ наиболее элегантен, так как не требует изменения текста запроса.
Часто разработчики пытаются решить задачу «в лоб», предлагая пользователям выбирать поля через точку: Номенклатура.Родитель, Номенклатура.Родитель.Родитель и так далее. Однако этот подход имеет серьезный недостаток. Если у вас в справочнике есть товары с разной глубиной вложенности (один лежит в папке 2-го уровня, а другой — в папке 4-го уровня), то поле Номенклатура.Родитель для них вернет папки совершенно разных уровней. В результате колонки в отчете будут заполнены хаотично.
Чтобы гарантировать, что в первой колонке всегда будет отображаться только корневая папка (1-й уровень), во второй — только подпапка (2-й уровень) и так далее, мы можем использовать выравнивание с помощью системной функции Уровень(). Рассмотрим пример настройки вычисляемых полей для справочника с максимальной вложенностью в 3 уровня:
Родитель_1_Уровня со следующим выражением:
Выбор
Когда Номенклатура.Уровень() = 1 Тогда Номенклатура.Родитель
Когда Номенклатура.Уровень() = 2 Тогда Номенклатура.Родитель.Родитель
Когда Номенклатура.Уровень() = 3 Тогда Номенклатура.Родитель.Родитель.Родитель
Иначе Неопределено
Конец
Родитель_2_Уровня:
Выбор
Когда Номенклатура.Уровень() = 2 Тогда Номенклатура.Родитель
Когда Номенклатура.Уровень() = 3 Тогда Номенклатура.Родитель.Родитель
Иначе Неопределено
Конец
Родитель_3_Уровня:
Выбор
Когда Номенклатура.Уровень() = 3 Тогда Номенклатура.Родитель
Иначе Неопределено
Конец
Преимущество метода: Данный способ чрезвычайно удобен для конечного пользователя. В режиме «1С:Предприятие» в настройках отчета (вкладка «Выбранные поля») пользователь может простыми галочками определять, какие колонки ему нужны в данный момент. Настройки СКД автоматически скроют или покажут соответствующие столбцы без деформации структуры таблицы.
Если мы хотим решить задачу исключительно визуальными настройками компоновки данных без написания формул в вычисляемых полях, мы можем применить специальный трюк со структурой настроек СКД.
Проанализируем алгоритм настройки:
Товар, а второму дадим псевдоним ТоварИерархия.ТоварИерархия. В свойствах этой группировки укажем тип группировки: Только иерархия (это заставит СКД выводить исключительно родительские папки).СистемныеПоля.Уровень = 1. Очень важно в свойствах элемента отбора указать параметр Применять: Только для иерархии. Это ограничит вывод только самым верхним уровнем папок.Нет. Это скроет стандартный «сдвиг» строк и предотвратит образование лесенки.Товар). В выбранные поля отчета вынесем одновременно и ТоварИерархия, и Товар.В результате СКД сопоставит родителя верхнего уровня и конечный товар в рамках одной строки, выведя их в разные колонки.
Бывают ситуации, когда стандартные таблицы запроса (например, виртуальные таблицы остатков и оборотов) работают некорректно или медленно при попытке соединить их с таблицами иерархии справочников. В этом случае наиболее производительным решением будет разделение данных на уровне наборов данных СКД и последующее их связывание.
Выполним следующие шаги для настройки связей:
ВЫБРАТЬ
ТоварыНаСкладах.Склад КАК Склад,
ТоварыНаСкладах.Номенклатура КАК Товар,
ТоварыНаСкладах.ВНаличииОстаток КАК Остаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладах
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка,
Номенклатура.Родитель КАК Родитель
ИЗ
Справочник.Номенклатура КАК Номенклатура
НаборДанных1НаборДанных2Товар = СсылкаНаборДанных2НаборДанных2Родитель = СсылкаБлагодаря такой настройке связей, СКД самостоятельно произведет рекурсивный подъем по дереву групп для каждой строки остатков. После этого мы сможем без труда обращаться к родительским группам любого уровня в рамках одной строки отчета, не перегружая основной запрос тяжелыми левыми соединениями. При необходимости можно использовать инструмент для построения дерева элементов и произвольной иерархии в СКД.
Мы рассмотрели четыре принципиально разных подхода к решению задачи вывода иерархии в строку: