Как в запросе 1С вывести все элементы из папок и подпапок с помощью оператора «В ИЕРАРХИИ»

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

При работе со справочниками в 1С, имеющими иерархическую структуру (например, Номенклатура), часто возникает задача получить список всех товаров, входящих в определенную группу, включая все вложенные подпапки. Стандартный оператор ГДЕ Ссылка В (&СписокЗначений) здесь не поможет, так как он проверяет только прямое соответствие. Для решения таких задач в языке запросов 1С предусмотрен специальный оператор В ИЕРАРХИИ. Однако на практике начинающие разработчики часто сталкиваются с тем, что запрос либо ничего не возвращает, либо возвращает неполные данные.

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

Разбираем принцип работы оператора В ИЕРАРХИИ

Давайте проанализируем, как работает этот оператор. В отличие от простого сравнения, В ИЕРАРХИИ заставляет систему рекурсивно просматривать все уровни вложенности. Если мы передаем в качестве параметра ссылку на папку «Бытовая техника», система найдет не только элементы, у которых родителем является эта папка, но и все элементы во вложенных папках «Холодильники», «Стиральные машины» и так далее. При необходимости решить обратную задачу и получить список родителей всех уровней для элементов справочника можно использовать инструмент для интерактивного формирования запроса получения родителей всех уровней.

Рассмотрим типичную ошибку. Если мы попытаемся использовать условие ГДЕ Номенклатура.Родитель В ИЕРАРХИИ(&Группа), мы получим только те элементы, которые находятся внутри подпапок, но пропустим элементы, лежащие непосредственно в самой папке «Группа». Правильный подход — применять условие непосредственно к самой ссылке элемента.

Решение 1: Передача ссылки в параметр запроса

Самый простой и правильный способ — передать в запрос готовую ссылку на нужную нам группу. Рассмотрим пример кода:


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка,
    Номенклатура.Артикул КАК Артикул,
    Номенклатура.Наименование КАК Наименование
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Ссылка В ИЕРАРХИИ(&ГруппаСсылка)
    И Номенклатура.ЭтоГруппа = ЛОЖЬ

В данном примере мы используем условие Номенклатура.Ссылка В ИЕРАРХИИ(&ГруппаСсылка). Важно понимать, что в параметр &ГруппаСсылка должна быть передана именно ссылка (объект типа СправочникСсылка.Номенклатура), а не строка с кодом или наименованием.

Также обратите внимание на условие Номенклатура.ЭтоГруппа = ЛОЖЬ. Оно позволяет отсечь сами папки из результата запроса, если нам нужны только конечные карточки товаров.

Решение 2: Получение ссылки по коду внутри запроса

Иногда в консоли запросов бывает сложно интерактивно выбрать папку (например, если настройки консоли ограничивают выбор только элементами). В этом случае можно воспользоваться вложенным запросом, чтобы система сама нашла ссылку по известному нам коду. Проанализируем этот метод:


ВЫБРАТЬ
    Номенклатура.Ссылка,
    Номенклатура.Артикул,
    Номенклатура.Наименование,
    Номенклатура.Родитель
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Ссылка В ИЕРАРХИИ(
        ВЫБРАТЬ
            ТекНоменклатура.Ссылка
        ИЗ
            Справочник.Номенклатура КАК ТекНоменклатура
        ГДЕ
            ТекНоменклатура.Код = &КодГруппы
    )
    И Номенклатура.ЭтоГруппа = ЛОЖЬ

Этот способ универсален. Мы передаем в параметр &КодГруппы обычную строку (например, "00001"), и запрос отрабатывает корректно, выбирая все дерево подчиненных элементов.

Почему консоль запросов не дает выбрать папку?

Выясним причину проблемы, описанной в сообщении №7 форума: «значение можно выбрать только элемент, а не папку». Это часто сбивает с толку. В платформе 1С для каждого справочника существует настройка «Выбор групп и элементов». Если в конфигурации для справочника Номенклатура установлено значение «Элементы», то в стандартных диалогах выбора папки будут доступны только для навигации, но не для выбора в качестве значения.

Как это обойти в консоли запросов:

  1. Проверьте тип параметра. Убедитесь, что выбран тип СправочникСсылка.Номенклатура.
  2. В некоторых консолях есть кнопка настроек или флажок «Выбор групп», который принудительно разрешает выбирать группы.
  3. Если настройки изменить нельзя, используйте «Решение 2» с поиском по коду через вложенный запрос.

Оптимизация производительности и особенности СУБД

Рассмотрим ситуацию с точки зрения производительности. Оператор В ИЕРАРХИИ является достаточно тяжелым для базы данных. На уровне SQL он транслируется в многократные соединения или использование обобщенных табличных выражений (CTE), чтобы пройтись по дереву родителей.

Посмотрим на важные рекомендации по оптимизации:

  1. Индексация: Поле Родитель в стандартных справочниках 1С всегда индексировано. Это критически важно для быстрой работы оператора В ИЕРАРХИИ. Не пытайтесь строить иерархию по неиндексированным реквизитам.
  2. Временные таблицы: Если вам нужно использовать результат иерархического отбора в нескольких местах сложного запроса, лучше сначала выгрузить ссылки во временную таблицу.
  3. Пустые ссылки: Будьте осторожны. Если в параметр &ГруппаСсылка передать пустую ссылку, поведение запроса может зависеть от версии платформы, но чаще всего результат будет пустым. Всегда проверяйте заполненность параметров перед выполнением.
  4. Глубина вложенности: Если ваше дерево номенклатуры имеет аномально большую глубину (сотни уровней), запрос может работать крайне медленно. Старайтесь ограничивать структуру справочников разумными пределами.

Использование в динамических списках

Разберем нюанс использования этого условия в динамических списках на формах. Если вы прописываете В ИЕРАРХИИ непосредственно в тексте запроса динамического списка, это может замедлить прокрутку и поиск. Платформа 1С лучше оптимизирует такие отборы, если они установлены через стандартные настройки компоновки данных (раздел «Отбор» в свойствах списка), а не жестко прописаны в коде ГДЕ.

Подводя итог, можно сказать, что для вывода элементов из всех подпапок наиболее надежным и понятным способом является использование конструкции Ссылка В ИЕРАРХИИ(&Параметр) с предварительной проверкой типа передаваемых данных. Совместное использование этого фильтра с флагом ЭтоГруппа = ЛОЖЬ гарантирует получение чистого списка товаров без лишних иерархических узлов. Для визуализации полученных иерархических данных в интерфейсе пользователя можно использовать обработку для вывода результатов запроса в дерево значений.

← На главную