В работе с иерархическими справочниками часто возникает необходимость знать, на каком уровне вложенности находится текущий элемент (корень – уровень 0, его непосредственные потомки – уровень 1 и т.д.). Ниже рассмотрены несколько проверенных способов получить этот уровень непосредственно в языке запросов 1С.
Использование встроенной функции Уровень
Самый простой и прямой способ – воспользоваться функцией Уровень, которая возвращает номер уровня элемента справочника в его дереве.
Пример запроса:
ВЫБРАТЬ Справочник.Подразделения.Ссылка КАК Подразделение, Справочник.Подразделения.Уровень КАК Уровень ИЗ Справочник.Подразделения КАК Справочник.Подразделения
Результат будет содержать две колонки: ссылка на элемент и его уровень вложенности.
Получение уровня через соединение с самим собой (самосоединение)
Если по какой‑то причине функция Уровень недоступна (например, в старых версиях платформы), уровень можно вычислить, посчитав количество родителей элемента.
Алгоритм: для каждого элемента считаем, сколько раз нужно перейти по полю Родитель, пока не получим пустую ссылку. Количество переходов – это искомый уровень.
Пример запроса с рекурсивным CTE (доступно с версии 8.3.12):
ВЫБРАТЬ Т.Ссылка КАК Подразделение, Т.Уровень КАК Уровень ИЗ ВЫБРАТЬ Ссылка, 0 КАК Уровень ИЗ Справочник.Подразделения ГДЕ Родитель ЕСТЬ NULL ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ Ссылка, Родитель.Уровень + 1 ИЗ Справочник.Подразделения ГДЕ Родитель НЕ ЕСТЬ NULL ) КАК Т
Запрос строит временную таблицу, где каждый элемент получает уровень, равный уровню его родителя плюс 1. Для небольших справочников такой подход работает быстро; для больших объёмов рекомендуется добавить индекс по полю Родитель.
Использование конструкции В ИЕРАРХИИ для выбора всех потомков и последующего подсчёта уровня
Конструкция В ИЕРАРХИИ позволяет выбрать элемент и все его потомки (или предков) за один проход. Если нам нужно знать уровень конкретного элемента относительно выбранного корня, можно воспользоваться следующим приёмом:
- Выбрать все элементы, начиная с нужного узла, с указанием уровня через псевдополе
УровеньВИерархии(доступно в некоторых конфигурациях). - Отфильтровать нужный элемент и взять его уровень.
Пример (если в конфигурации есть функция УровеньВИерархии):
ВЫБРАТЬ Ссылка КАК Подразделение, УровеньВИерархии КАК Уровень ИЗ Справочник.Подразделения ГДЕ Ссылка В ИЕРАРХИИ (&КорневойЭлемент)
Здесь параметр &КорневойЭлемент – ссылка на элемент, от которого ведём иерархию (например, корень справочника).
Динамическое формирование текста запроса в зависимости от требуемого уровня
Иногда удобно собрать запрос строкой, добавляя нужное количество соединений с таблицей справочника через поле Родитель. Такой подход полезен, когда нужно получить не только уровень, но и цепочку родителей.
Пример кода на 1С:
Функция ПолучитьЗапросСУровнем(ЭлементСправочника) Экспорт
Запрос = Новый Запрос;
Текст =
"ВЫБРАТЬ
Ссылка КАК Подразделение,
%1 КАК Уровень
ИЗ
Справочник.Подразделения КАК Справочник.Подразделения
ГДЕ
Ссылка = &Элемент";
// Вычисляем уровень через функцию Уровень
Текст = СтрЗаменить(Текст, "%1", "Справочник.Подразделения.Уровень");
Запрос.Текст = Текст;
Запрос.УстановитьПараметр("Элемент", ЭлементСправочника);
Возврат Запрос;
КонецФункции
Эта функция возвращает готовый объект Запрос, который можно выполнить и получить уровень нужного элемента.
Получение уровня через временную таблицу и цикл (для учебных целей)
Если необходимо показать процесс поэтапно, можно воспользоваться временной таблицей и циклом:
ТаблицаУровней = Новый ТаблицаЗначения;
ТаблицаУровней.Колонки.Добавить("Ссылка");
ТаблицаУровней.Колонки.Добавить("Уровень");
Элемент = Справочник.Подразделения.НайтиПоНаименованию("Отдел продаж");
Уровень = 0;
Пока Элемент <> Неопределено Цикл
НоваяСтрока = ТаблицаУровней.Добавить;
НоваяСтрока.Ссылка = Элемент;
НоваяСтрока.Уровень = Уровень;
Элемент = Элемент.Родитель;
Уровень = Уровень + 1;
КонецЦикла;
// ТаблицаУровней теперь содержит цепочку от выбранного элемента до корня с уровнями.
После заполнения таблицы можно выполнить запрос к ней, если требуется объединить с другими данными.
- Для большинства задач достаточно функции
Уровень– она проста, быстра и не требует дополнительных соединений. - Если функция недоступна, используйте самосоединение или рекурсивный CTE для вычисления количества родителей.
- Конструкция
В ИЕРАРХИИудобна, когда нужно получить не только уровень, но и набор предков/потомков одновременно. - Динамическое формирование запроса полезно в метапрограммировании, когда уровень определяется во время выполнения.
- Для учебных целей и отладки можно применять временные таблицы и циклы, но в продакшене такие методы обычно менее эффективны.
Выбирайте способ, который лучше всего соответствует вашей конфигурации, объёму данных и требованиям к производительности. Надеюсь, представленные примеры помогут вам быстро и надёжно получать уровень элементов справочника в запросах 1С:Предприятие.