Как вывести иерархический справочник в плоский отчет с помощью СКД?

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

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

Метод первый: Использование ресурсов для «закрепления» контекста

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

  1. В тексте запроса набора данных получите поле Ссылка. Для дубликата этого поля установите синоним, например, СсылкаДоп.
  2. Перейдите на вкладку Ресурсы и добавьте поле СсылкаДоп. В выражении просто укажите имя поля СсылкаДоп без каких-либо агрегатных функций (например, Сумма или Максимум нам не нужны).
  3. В настройках отчета создайте группировку по полю Ссылка (без иерархии). В настройках этой группировки перейдите на вкладку Другие настройки (где также можно настроить скрытие пустых столбцов) и для параметра Расположение группировки установите значение Нет.
  4. Под этой группировкой добавьте подчиненную группировку по полю Ссылка, но уже с включенной иерархией.
  5. В эту подчиненную группировку выведите ресурс СсылкаДоп.
  6. Чтобы скрыть лишние уровни, добавьте группу отборов с применением После группировки или для иерархии и установите отбор: Системные поля.Уровень равно 2 (или иное значение, соответствующее глубине вашей задачи). Также рекомендуется установить свойство Выводить отбор в значение Нет.

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

Метод второй: Перенос вычислений во внешний модуль

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

Рассмотрим пример реализации функции, которую можно вызывать из вычисляемых полей СКД:


Функция ПолучитьРодителяВерхнегоУровня(Ссылка) Экспорт
    Если Ссылка.Пустая() Тогда
        Возврат Ссылка;
    КонецЕсли;
    
    Родитель = Ссылка.Родитель;
    Пока ЗначениеЗаполнено(Родитель.Родитель) Цикл
        Родитель = Родитель.Родитель;
    КонецЦикла;
    
    Возврат Родитель;
КонецФункции

Чтобы этот метод работал максимально эффективно, рекомендуем:

Практические рекомендации по оптимизации

Анализируя задачу «вылизывания» производительности, мы должны помнить о главном правиле: избегайте обращений через точку в запросах. Если вам нужно получить данные из вышестоящих уровней иерархии для 100 000 элементов, лучше заранее подготовить плоскую таблицу в пакетном запросе.

Рассмотрим структуру пакетного запроса:


ВЫБРАТЬ 
    Спр.Ссылка КАК Элемент,
    Спр.Родитель КАК Родитель
ПОМЕСТИТЬ ВТ_Иерархия
ИЗ Справочник.Номенклатура КАК Спр;

ВЫБРАТЬ 
    ВТ.Элемент,
    ВТ.Родитель КАК КорневойРодитель
ИЗ ВТ_Иерархия КАК ВТ
...

Используя транзитивное замыкание (или последовательное левое соединение фиксированной глубины), вы получите плоскую структуру, которую СКД «проглотит» без каких-либо сложностей. Этот метод является наиболее предпочтительным для высоконагруженных отчетов, так как вся тяжелая работа выполняется на стороне SQL, а не на стороне сервера приложений или движка компоновки данных.

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

← На главную