Структура иерархического справочника запросом

19.04.13

Разработка - Запросы

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

Допустим имеем иерархический справочник "Подразделения" с неизвестным (неограниченным) уровнем вложенности:

Подр1

Подр11

Подр12

Подр121

Подр122

Подр13

...

ПодрN

И требуется получить таблицу следующей структуры:

Подразделение Уровень
0
Уровень
1
Уровень
2
... Уровень
Макс-1
Уровень
Макс
Подр1 Подр1          
Подр11 Подр1 Подр11        
Подр12 Подр1 Подр12        
Подр121 Подр1 Подр12 Подр121      
Подр122 Подр1 Подр12 Подр122      
...            
ПодрN ПодрN          

 

Пример:

Пример

 

Предлагаю следующий вариант решения:


// Определим максимальный уровень иерархии справочника
Запрос = Новый Запрос;
Запрос.Текст =
    "ВЫБРАТЬ
    |   Подразделения.Ссылка
    |ИЗ
    |   Справочник.Подразделения КАК Подразделения";
Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();
МаксУровень = 0;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    МаксУровень = Макс(ВыборкаДетальныеЗаписи.Ссылка.Уровень(), МаксУровень);
КонецЦикла;

// Соберем текст запроса для получения следующей структуры полей выборки:
//      Подразделение, Уровень0, Уровень1, ..., УровеньN-1, УровеньN.
// где N - максимальный уровень иерархии.

// Начало текста запроса
Запрос.Текст =
    "ВЫБРАТЬ
    |   *
    |ИЗ
    |   (";
// Нулевой уровень иерархии
ТекущийУровень = 0;
Запрос.Текст = Запрос.Текст + "
    |ВЫБРАТЬ
    |   Подразделения.Ссылка КАК Подразделение
    |   , Подразделения.Ссылка КАК Уровень0";
Для Сч=1 По МаксУровень Цикл
    Запрос.Текст = Запрос.Текст + "
        |   , ЗНАЧЕНИЕ(Справочник.Подразделения.ПустаяСсылка) КАК Уровень"+Сч;
КонецЦикла;
Запрос.Текст = Запрос.Текст + "
    |ИЗ
    |   Справочник.Подразделения КАК Подразделения
    |ГДЕ
    |   Подразделения.Родитель = ЗНАЧЕНИЕ(Справочник.Подразделения.ПустаяСсылка)";
// Последующие уровни иерархии.
Для ТекущийУровень = 1 По МаксУровень Цикл
    Запрос.Текст = Запрос.Текст + "
        |
        |ОБЪЕДИНИТЬ ВСЕ
        |
        |ВЫБРАТЬ
        |   Подразделения.Ссылка КАК Подразделение";
    Для Сч1=0 По ТекущийУровень-1 Цикл
        Запрос.Текст = Запрос.Текст + "
        |   , Подразделения";
        Для Сч2=1 по ТекущийУровень-Сч1 Цикл
            Запрос.Текст = Запрос.Текст + ".Родитель";
        КонецЦикла;
        Запрос.Текст = Запрос.Текст + " КАК Уровень"+Сч1;
    КонецЦикла;
    Запрос.Текст = Запрос.Текст + "
        |   , Подразделения.Ссылка КАК Уровень"+ТекущийУровень;
    Для Сч=ТекущийУровень+1 По МаксУровень Цикл
        Запрос.Текст = Запрос.Текст + "
            |   , ЗНАЧЕНИЕ(Справочник.Подразделения.ПустаяСсылка) КАК Уровень"+Сч;
    КонецЦикла;
    Запрос.Текст = Запрос.Текст + "
        |ИЗ
        |   Справочник.Подразделения КАК Подразделения
        |ГДЕ
        |   Подразделения.Родитель";
    Для Сч2=1 по ТекущийУровень Цикл
        Запрос.Текст = Запрос.Текст + ".Родитель";
    КонецЦикла;
    Запрос.Текст = Запрос.Текст + " = ЗНАЧЕНИЕ(Справочник.Подразделения.ПустаяСсылка)";
КонецЦикла;
// Финиш текста запроса
Запрос.Текст = Запрос.Текст + "
    |   ) КАК Структура
    |УПОРЯДОЧИТЬ ПО
    |   Структура.Уровень0.Наименование";
Для Сч=1 По МаксУровень Цикл
    Запрос.Текст = Запрос.Текст + "
        |   , Структура.Уровень"+Сч+".Наименование";
КонецЦикла;

Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    // Обход выборки.
КонецЦикла;

 

У данного решения есть минусы, которые я пока не смог обойти:

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

2. При большом максимальном уровне вложенности может быть будут проблемы с запросом (в местах, где множится "...Родитель.Родитель.Родитель..."). Я тестировал на 20 уровне вложенности.

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

15500 руб.

02.09.2020    181560    1007    403    

959

Обновление 1С Запросы Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 Абонемент ($m)

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

2 стартмани

06.02.2025    2041    16    XilDen    26    

35

Запросы Программист Бесплатно (free)

Увидел cheatsheet по SQL и захотелось нарисовать подобное, но про запросы.

18.10.2024    12825    sergey279    18    

65

Запросы Программист Платформа 1С v8.3 Запросы 1C:Бухгалтерия Бесплатно (free)

Столкнулся с интересной ситуацией, которую хотел бы разобрать, ввиду её неочевидности. Речь пойдёт про использование функции запроса АВТОНОМЕРЗАПИСИ() и проблемы, которые могут возникнуть.

11.10.2024    7907    XilDen    36    

90

Запросы Программист Запросы Бесплатно (free)

Отлаживая взаимодействие с базой данных, мы регулярно сталкиваемся с зависающими или подозрительно долго выполняющимися обращениями, негативно влияющими на производительность. О том, как в PostgreSQL выявить подозрительные запросы, основываясь на доступной о них информации, расскажем в статье.

16.08.2024    10516    user1840182    5    

29

Математика и алгоритмы Запросы Программист Платформа 1С v8.3 Запросы Бесплатно (free)

Рассмотрим быстрый алгоритм поиска дублей с использованием hash функции по набору полей шапки и табличных частей.

08.07.2024    3132    ivanov660    9    

22

Запросы СКД Программист Стажер Система компоновки данных Россия Бесплатно (free)

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

15.05.2024    12812    implecs    6    

50
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. пользователь 19.04.13 21:51
Сообщение было скрыто модератором.
...
2. AlexProg 115 19.04.13 22:07 Сейчас в теме
(1) Eugeneer, чья бы корова мычала, твоя бы молчала.
3. ildarovich 7953 20.04.13 22:49 Сейчас в теме
В статье Уровни, глубина, прародители, циклы и аналоги запросом показано, как одним запросом быстро получить в том числе и максимальный уровень справочника.
Оставьте свое сообщение