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

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

При построении отчетов, выгрузке данных в Excel или выводе иерархических структур на форму перед разработчиками часто встает задача: отобразить данные справочника так же, как они представлены в стандартной форме списка. То есть, чтобы на каждом уровне вложенности сначала шли группы (папки), отсортированные по алфавиту, а уже под ними — элементы (товары/услуги).

Если написать стандартный запрос с иерархией, платформа может перемешать папки и элементы или вывести элементы в самом начале списка. В этой статье мы подробно разберем причины такого поведения и рассмотрим три проверенных практических метода решения этой задачи.

Причина проблемы: почему стандартная сортировка ломает иерархию

Когда мы используем в запросе конструкцию ИТОГИ ПО Ссылка ИЕРАРХИЯ, система строит дерево на основе родительских связей. Однако стандартный механизм упорядочивания СУБД по умолчанию не разделяет папки и элементы, если мы явно не указали это в условиях. Сортировка по наименованию просто выстроит все записи текущего уровня по алфавиту, из-за чего папка на букву "Я" окажется в самом конце уровня, уступив место элементам на буквы "А", "Б" и так далее.

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

---

Решение 1: Сортировка по вспомогательному полю в запросе

Самый популярный способ упорядочить данные непосредственно в базе данных — это создание искусственного поля сортировки. Мы можем использовать реквизит справочника ЭтоГруппа. Поскольку тип этого реквизита — Булево, значение ИСТИНА (для групп) при сортировке по убыванию всегда будет находиться выше, чем ЛОЖЬ (для элементов). Также мы можем явно задать числовые веса для типов записей через условное выражение ВЫБОР.

Рассмотрим пример запроса, использующего числовое поле сортировки:


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

УПОРЯДОЧИТЬ ПО
    ПорядокСортировки,
    Наименование
ИТОГИ ПО
    Ссылка ИЕРАРХИЯ
АВТОУПОРЯДОЧИВАНИЕ

Как работает этот код:

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

---

Решение 2: Стратегия «ТОЛЬКО ИЕРАРХИЯ» для исключения дублирования папок

При выгрузке иерархического запроса в ДеревоЗначений разработчики часто сталкиваются с дублированием данных: папка выгружается сначала как строка-группировка, а затем дублируется внутри себя как детальная запись. Чтобы получить чистое и аккуратное дерево (где ветками будут только папки, а листьями — только элементы), используется стратегия исключения групп из выборки с последующим расчетом итогов по иерархии.

Проанализируем следующий пример запроса:


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

Разберем этот механизм по шагам:

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

---

Решение 3: Программная сортировка Дерева Значений после запроса

Бывают ситуации, когда логика построения отчетов накладывает свои ограничения, и СУБД возвращает сырые данные в неоптимальном порядке. В этом случае самым надежным и легко контролируемым решением будет программная сортировка уже выгруженного объекта ДеревоЗначений средствами встроенного языка 1С.

Для реализации этого метода нам обязательно нужно выбрать признак ЭтоГруппа в самом запросе. Посмотрим на пример программной реализации:


// 1. Инициализируем и выполняем запрос
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Номенклатура.Ссылка КАК Ссылка,
    |	Номенклатура.Наименование КАК Наименование,
    |	Номенклатура.ЭтоГруппа КАК ЭтоГруппа
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |	НЕ Номенклатура.ПометкаУдаления
    |ИТОГИ ПО
    |	Ссылка ИЕРАРХИЯ";

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

// 2. Выгружаем результат в Дерево Значений с иерархией
ДеревоНоменклатуры = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);

// 3. Сортируем дерево программно
// Первый параметр - поля и направления сортировки
// Второй параметр (Истина) указывает, что нужно отсортировать все подчиненные уровни рекурсивно
ДеревоНоменклатуры.Строки.Сортировать("ЭтоГруппа Убыв, Наименование Возр", Истина);

Важные особенности программного метода:

---

Какое решение выбрать?

Выбор конкретного метода зависит от архитектуры вашей задачи:

← На главную