Как скрыть пустые группы при отборе по реквизиту в иерархическом справочнике (обычные формы)

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

В разработке на платформе 1С:Предприятие 8.2 и 8.3 в режиме обычного приложения часто возникает классическая задача: необходимо выполнить отбор в справочнике по определенному реквизиту. При этом критически важно сохранить иерархическую структуру (отображение «деревом»), но скрыть те группы, которые не содержат элементов, подходящих под условия фильтра. Разберем, почему стандартный механизм СправочникСписок не справляется с этой задачей «из коробки», и проанализируем эффективные методы обхода этого ограничения.

Почему стандартный отбор оставляет «пустые» папки

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

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

Способ 1. Программный фильтр по списку ссылок (Метод «В списке»)

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

Разберем алгоритм реализации:

  1. Создадим запрос, который выберет все элементы, соответствующие нашему условию.
  2. В этом же запросе или кодом определим все родительские группы (всех уровней вложенности) для найденных элементов.
  3. Выгрузим результат в массив или СписокЗначений.
  4. Установим отбор в табличном поле СправочникСписок.Отбор.Ссылка с видом сравнения ВидСравнения.ВСписке.

Посмотрим на пример кода, который реализует эту логику:


// Предположим, нам нужно отобрать номенклатуру по реквизиту "Менеджер"
Процедура УстановитьИерархическийОтбор()
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ РАЗЛИЧНЫЕ
    |	Номенклатура.Ссылка КАК Ссылка
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |	Номенклатура.Менеджер = &Менеджер
    |
    |УПОРЯДОЧИТЬ ПО
    |	Номенклатура.Ссылка ИЕРАРХИЯ";
    
    Запрос.УстановитьПараметр("Менеджер", ВыбранныйМенеджер);
    
    РезультатЗапроса = Запрос.Выполнить();
    СписокСсылок = Новый СписокЗначений;
    СписокСсылок.ЗагрузитьЗначения(РезультатЗапроса.Выгрузить().ВыгрузитьКолонку("Ссылка"));
    
    // Применяем отбор к СправочникСписок
    ОтборСсылка = СправочникСписок.Отбор.Ссылка;
    ОтборСсылка.ВидСравнения = ВидСравнения.ВСписке;
    ОтборСсылка.Значение = СписокСсылок;
    ОтборСсылка.Использование = Истина;
    
КонецПроцедуры

Важный момент: использование конструкции УПОРЯДОЧИТЬ ПО ... ИЕРАРХИЯ в запросе позволяет автоматически включить в результат все вышестоящие группы. Если мы передадим в список только конечные элементы, то при включенной иерархии в списке они могут просто исчезнуть, так как платформа не найдет их «родителей» в разрешенном списке ссылок.

Способ 2. Использование Построителя Отчета

Если справочник очень большой, и формирование списка ссылок через запрос начинает занимать много времени, проанализируем альтернативу — использование ПостроительОтчета. Этот объект в обычных формах позволяет выводить данные в табличное поле, имитируя поведение динамического списка.

Рассмотрим преимущества этого метода:

Однако у этого метода есть существенный минус: вы теряете стандартные возможности «живого» списка справочника (быстрое добавление, перетаскивание элементов Drag-and-drop, интерактивное изменение иерархии пользователем). Этот метод хорош для форм выбора или специализированных АРМ, но редко подходит для основной формы списка справочника.

Способ 3. Ограничение прав на уровне записей (RLS)

Если задача отбора стоит не в плоскости удобства интерфейса, а в плоскости безопасности (например, менеджер должен видеть только свои группы и товары), рассмотрим механизм RLS (Row Level Security). Это единственный способ, при котором данные фильтруются на уровне СУБД еще до попадания в приложение.

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

Оптимизация производительности: индексирование

Независимо от выбранного способа, мы должны обеспечить скорость работы. Если вы выполняете отбор по какому-либо реквизиту, убедитесь, что для этого реквизита в конфигураторе установлено свойство Индексировать. Без индекса любой программный отбор в обычном приложении на справочнике объемом более 10-20 тысяч записей будет вызывать заметные задержки (фризы) интерфейса при каждом обновлении.

Резюме

Мы выяснили, что штатного переключателя «Скрывать пустые группы» в СправочникСписок обычного приложения не существует. Для решения задачи мы рекомендуем использовать программную установку отбора по полю Ссылка с предварительным получением списка разрешенных объектов через запрос с иерархией. Это решение является сбалансированным по сложности реализации и предсказуемости результата.

← На главную