Как упорядочить результат запроса по справочнику с сохранением иерархии в 1С?

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

При выборке данных из иерархических справочников с помощью запроса разработчики часто сталкиваются с задачей отображения элементов в том же порядке, в котором они представлены в пользовательском интерфейсе: с разделением на группы и подчиненные элементы, а также с сортировкой внутри каждого родителя по наименованию или коду. Если написать обычное предложение УПОРЯДОЧИТЬ ПО Наименование, иерархия разрушится, а папки и элементы перемешаются в едином алфавитном списке. Разберем основные способы решения этой задачи, их внутреннюю механику, синтаксические особенности и влияние на производительность.

Способ 1. Использование ключевого слова АВТОУПОРЯДОЧИВАНИЕ

Самый быстрый и простой способ получить порядок строк, аналогичный отображению справочника в дереве, — добавить в конец текста запроса конструкцию АВТОУПОРЯДОЧИВАНИЕ без явного указания полей.

Посмотрим на пример запроса:


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка,
    Номенклатура.Наименование КАК Наименование,
    Номенклатура.Код КАК Код
ИЗ
    Справочник.Номенклатура КАК Номенклатура
АВТОУПОРЯДОЧИВАНИЕ

Проанализируем внутреннюю механику работы этого механизма. При обработке запроса с АВТОУПОРЯДОЧИВАНИЕ платформа 1С автоматически обращается к метаданным справочника и добавляет следующие критерии сортировки:

  1. Поле ЭтоГруппа (для справочников с видом «Иерархия групп и элементов»), чтобы папки всегда располагались выше обычных элементов внутри каждого родительского узла.
  2. Поле, заданное в свойствах метаданных («Способ упорядочивания списка» или «Основное представление» — чаще всего Наименование или Код).
  3. Поле Ссылка — для обеспечения строго детерминированного порядка записей при полном совпадении наименований.

Важные ограничения: ключевое слово АВТОУПОРЯДОЧИВАНИЕ нельзя использовать во вложенных запросах (кроме конструкций с ПЕРВЫЕ), а также совместно с секцией ИТОГИ. Кроме того, автоматическая сортировка по первичному ключу Ссылка в сложных запросах с большим количеством соединений может вызывать дополнительную нагрузку на СУБД.

Способ 2. Явное указание порядка с модификатором ИЕРАРХИЯ

Если нам необходимо получить плоский (линейный) список, но сохранить логику раскрытого дерева (когда сначала идет родитель, затем все его дочерние узлы, затем следующий родитель), мы можем применить ключевое слово ИЕРАРХИЯ непосредственно в секции УПОРЯДОЧИТЬ ПО.

Рассмотрим пример запроса:


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка,
    Номенклатура.Наименование КАК Наименование
ИЗ
    Справочник.Номенклатура КАК Номенклатура
УПОРЯДОЧИТЬ ПО
    Номенклатура.Ссылка ИЕРАРХИЯ,
    Наименование

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


Выборка = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.Прямой);
Пока Выборка.Следующий() Цикл
    УровеньВложенности = Выборка.Ссылка.Уровень();
    // Обработка данных с учетом уровня
КонецЦикла;

Обратите внимание: если справочник имеет вид «Иерархия элементов» (а не групп и элементов), у него отсутствует реквизит ЭтоГруппа. Попытка написать УПОРЯДОЧИТЬ ПО Номенклатура.ЭтоГруппа для такого объекта приведет к ошибке, поэтому использование Ссылка ИЕРАРХИЯ является более универсальным.

Способ 3. Построение дерева через ИТОГИ ПО ... ТОЛЬКО ИЕРАРХИЯ

Когда требуется получить древовидную структуру данных для рекурсивной обработки или построения сложных многоуровневых отчетов с подчиненными таблицами (например, характеристиками номенклатуры), разберем использование секции ИТОГИ.

Посмотрим на практический пример с соединением таблиц:


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка,
    Номенклатура.Код КАК Код,
    Номенклатура.Артикул КАК Артикул,
    ХарактеристикиНоменклатуры.Ссылка КАК Характеристика,
    Номенклатура.Наименование КАК Наименование
ИЗ
    Справочник.Номенклатура КАК Номенклатура
    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ХарактеристикиНоменклатуры КАК ХарактеристикиНоменклатуры
        ПО Номенклатура.Ссылка = ХарактеристикиНоменклатуры.Владелец
УПОРЯДОЧИТЬ ПО
    Наименование
ИТОГИ ПО
    Номенклатура.Ссылка ТОЛЬКО ИЕРАРХИЯ

Проанализируем нюанс работы ТОЛЬКО ИЕРАРХИЯ: на самом верхнем уровне запроса платформа всегда создает корневой виртуальный элемент с пустой ссылкой. Это стандартное поведение дерева итогов в платформе 1С. При программной обработке этот уровень обходится через специальный режим:


ВыборкаИерархия = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
Пока ВыборкаИерархия.Следующий() Цикл
    // Пропускаем пустую корневую ссылку при необходимости
    Если НЕ ЗначениеЗаполнено(ВыборкаИерархия.Ссылка) Тогда
        Продолжить;
    КонецЕсли;
    
    // Обработка узла дерева
КонецЦикла;

Альтернативные подходы

Разберем ситуации, когда использовать прямой запрос не обязательно:

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