Способы получения уровня вложенности элемента справочника в языке запросов 1С

Бесплатная консультация юриста

+7 (800) 302-87-29

Реклама jurik.ru

В работе с иерархическими справочниками часто возникает необходимость знать, на каком уровне вложенности находится текущий элемент (корень – уровень 0, его непосредственные потомки – уровень 1 и т.д.). Ниже рассмотрены несколько проверенных способов получить этот уровень непосредственно в языке запросов 1С.

Использование встроенной функции Уровень

Самый простой и прямой способ – воспользоваться функцией Уровень, которая возвращает номер уровня элемента справочника в его дереве.

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

ВЫБРАТЬ
 Справочник.Подразделения.Ссылка КАК Подразделение,
 Справочник.Подразделения.Уровень КАК Уровень
ИЗ
 Справочник.Подразделения КАК Справочник.Подразделения

Результат будет содержать две колонки: ссылка на элемент и его уровень вложенности.

Получение уровня через соединение с самим собой (самосоединение)

Если по какой‑то причине функция Уровень недоступна (например, в старых версиях платформы), уровень можно вычислить, посчитав количество родителей элемента.

Алгоритм: для каждого элемента считаем, сколько раз нужно перейти по полю Родитель, пока не получим пустую ссылку. Количество переходов – это искомый уровень.

Пример запроса с рекурсивным CTE (доступно с версии 8.3.12):

ВЫБРАТЬ
 Т.Ссылка КАК Подразделение,
 Т.Уровень КАК Уровень
ИЗ
 ВЫБРАТЬ
 Ссылка,
 0 КАК Уровень
 ИЗ
 Справочник.Подразделения
 ГДЕ
 Родитель ЕСТЬ NULL
 ОБЪЕДИНИТЬ ВСЕ
 ВЫБРАТЬ
 Ссылка,
 Родитель.Уровень + 1
 ИЗ
 Справочник.Подразделения
 ГДЕ
 Родитель НЕ ЕСТЬ NULL
) КАК Т

Запрос строит временную таблицу, где каждый элемент получает уровень, равный уровню его родителя плюс 1. Для небольших справочников такой подход работает быстро; для больших объёмов рекомендуется добавить индекс по полю Родитель.

Использование конструкции В ИЕРАРХИИ для выбора всех потомков и последующего подсчёта уровня

Конструкция В ИЕРАРХИИ позволяет выбрать элемент и все его потомки (или предков) за один проход. Если нам нужно знать уровень конкретного элемента относительно выбранного корня, можно воспользоваться следующим приёмом:

  1. Выбрать все элементы, начиная с нужного узла, с указанием уровня через псевдополе УровеньВИерархии (доступно в некоторых конфигурациях).
  2. Отфильтровать нужный элемент и взять его уровень.

Пример (если в конфигурации есть функция УровеньВИерархии):

ВЫБРАТЬ
 Ссылка КАК Подразделение,
 УровеньВИерархии КАК Уровень
ИЗ
 Справочник.Подразделения
ГДЕ
 Ссылка В ИЕРАРХИИ (&КорневойЭлемент)

Здесь параметр &КорневойЭлемент – ссылка на элемент, от которого ведём иерархию (например, корень справочника).

Динамическое формирование текста запроса в зависимости от требуемого уровня

Иногда удобно собрать запрос строкой, добавляя нужное количество соединений с таблицей справочника через поле Родитель. Такой подход полезен, когда нужно получить не только уровень, но и цепочку родителей.

Пример кода на 1С:

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

 // Вычисляем уровень через функцию Уровень
 Текст = СтрЗаменить(Текст, "%1", "Справочник.Подразделения.Уровень");
 
 Запрос.Текст = Текст;
 Запрос.УстановитьПараметр("Элемент", ЭлементСправочника);
 Возврат Запрос;
КонецФункции

Эта функция возвращает готовый объект Запрос, который можно выполнить и получить уровень нужного элемента.

Получение уровня через временную таблицу и цикл (для учебных целей)

Если необходимо показать процесс поэтапно, можно воспользоваться временной таблицей и циклом:

ТаблицаУровней = Новый ТаблицаЗначения;
ТаблицаУровней.Колонки.Добавить("Ссылка");
ТаблицаУровней.Колонки.Добавить("Уровень");

Элемент = Справочник.Подразделения.НайтиПоНаименованию("Отдел продаж");
Уровень = 0;
Пока Элемент <> Неопределено Цикл
 НоваяСтрока = ТаблицаУровней.Добавить;
 НоваяСтрока.Ссылка = Элемент;
 НоваяСтрока.Уровень = Уровень;
 Элемент = Элемент.Родитель;
 Уровень = Уровень + 1;
КонецЦикла;
// ТаблицаУровней теперь содержит цепочку от выбранного элемента до корня с уровнями.

После заполнения таблицы можно выполнить запрос к ней, если требуется объединить с другими данными.

  • Для большинства задач достаточно функции Уровень – она проста, быстра и не требует дополнительных соединений.
  • Если функция недоступна, используйте самосоединение или рекурсивный CTE для вычисления количества родителей.
  • Конструкция В ИЕРАРХИИ удобна, когда нужно получить не только уровень, но и набор предков/потомков одновременно.
  • Динамическое формирование запроса полезно в метапрограммировании, когда уровень определяется во время выполнения.
  • Для учебных целей и отладки можно применять временные таблицы и циклы, но в продакшене такие методы обычно менее эффективны.

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