Как правильно использовать отбор по группам и элементам справочника в запросах 1С: операторы В и В ИЕРАРХИИ

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

При построении отчетов и выборок в платформе 1С:Предприятие разработчики часто сталкиваются с задачей установки отборов по справочникам. Если пользователь выбирает конкретный элемент, обычно достаточно простого равенства (=). Однако если в качестве условия передается группа справочника (папка), возникает вопрос: какую конструкцию использовать — В или В ИЕРАРХИИ, в чем их принципиальная разница и как это влияет на производительность запроса?

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

В чем разница между операторами В и В ИЕРАРХИИ

Для понимания механизма работы сравним назначение и поведение обоих операторов языка запросов 1С:

  1. Оператор В (проверка вхождения в список):

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

  2. Оператор В ИЕРАРХИИ (проверка принадлежности к ветке иерархии):

    Это специализированная конструкция платформы 1С, не имеющая прямого аналога в стандартном синтаксисе SQL. Она проверяет, входит ли проверяемое значение в иерархическую ветку переданного узла (родителя). В результат попадают как сам указанный узел, так и все подчиненные ему элементы и подгруппы на всех уровнях вложенности.

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

Реализация динамического отбора в коде

Рассмотрим, как часто пытаются решить задачу разделения элементов и групп и как сделать код проще и надежнее.

Нередко разработчики пишут избыточные проверки с помощью метода ЭтоГруппа(), усложняя текст модуля:


Если ЗначениеЗаполнено(КонтрагентОтбор) И НЕ КонтрагентОтбор.ЭтоГруппа() Тогда
    Запрос.Текст = Запрос.Текст + " И Таблица.Ссылка.Контрагент = &Контрагент";
ИначеЕсли ЗначениеЗаполнено(КонтрагентОтбор) И КонтрагентОтбор.ЭтоГруппа() Тогда
    Запрос.Текст = Запрос.Текст + " И Таблица.Ссылка.Контрагент В ИЕРАРХИИ(&Контрагент)";
КонецЕсли;

Поскольку конструкция В ИЕРАРХИИ одинаково успешно находит и конкретный элемент, и группу со всеми вложенными позициями, условие можно сократить без потери функциональности:


Если ЗначениеЗаполнено(КонтрагентОтбор) Тогда
    Запрос.Текст = Запрос.Текст + "
        |    И Таблица.Ссылка.Контрагент В ИЕРАРХИИ(&Контрагент)";
    Запрос.УстановитьПараметр("Контрагент", КонтрагентОтбор);
КонецЕсли;

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

Ограничения и влияние на производительность

Несмотря на удобство, оператор В ИЕРАРХИИ требует осторожного применения из-за особенностей его трансляции на уровень СУБД:

  1. Нагрузка на СУБД: При выполнении условия В ИЕРАРХИИ платформа 1С выполняет обращение к специальным служебным таблицам иерархии метаданных. На уровне SQL генерируются сложные подзапросы или соединения, что нередко приводит к отказу оптимизатора СУБД от использования индексов и переходу к сканированию всей таблицы (Table Scan / Index Scan).
  2. Типы объектов: Конструкция применима исключительно к объектам с включенной иерархией (иерархические справочники, планы видов характеристик, планы счетов). Попытка применить ее к неиерархическому справочнику вызовет синтаксическую ошибку запроса.
  3. Фильтрация виртуальных таблиц: Условие В ИЕРАРХИИ обязательно должно накладываться в параметрах виртуальной таблицы (например, среза последних или остатков), а не в секции ГДЕ, иначе сначала в память будут прочитаны все записи регистра, и лишь затем отфильтрованы.

Способы оптимизации запросов с иерархией

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

  1. Разгрузка основного запроса через временную таблицу (ВТ):

    Если запрос соединяет несколько больших таблиц, эффективнее всего сначала выбрать все входящие в иерархию элементы во временную таблицу и проиндексировать ее:

    
    ВЫБРАТЬ
        Номенклатура.Ссылка КАК Ссылка
    ПОМЕСТИТЬ ВТ_СоставГруппы
    ИЗ
        Справочник.Номенклатура КАК Номенклатура
    ГДЕ
        Номенклатура.Ссылка В ИЕРАРХИИ(&ГруппаНоменклатуры)
    ИНДЕКСИРОВАТЬ ПО
        Ссылка
    ;
    
    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ
        ПродажиОбороты.Номенклатура КАК Номенклатура,
        ПродажиОбороты.КоличествоОборот КАК Количество
    ИЗ
        РегистрНакопления.Продажи.Обороты(
            &НачалоПериода,
            &КонецПериода,
            ,
            Номенклатура В (ВЫБРАТЬ ВТ_СоставГруппы.Ссылка ИЗ ВТ_СоставГруппы КАК ВТ_СоставГруппы)) КАК ПродажиОбороты
    
  2. Предварительное получение плоского массива:

    Для небольших справочников с неглубокой структурой можно заранее получить массив ссылок отдельным легким запросом, после чего передать его в основной запрос через оператор точного вхождения В (&МассивСсылок), что позволит СУБД построить оптимальный план выполнения.

  3. Использование Системы компоновки данных (СКД):

    При разработке отчетов рекомендуется передавать задачу фильтрации механизмам СКД. Компоновщик данных динамически формирует оптимальный текст SQL-запроса, корректно обрабатывая виды сравнения В иерархии и В иерархии (списка).

← На главную