Как скрыть пустые ветки иерархии в динамическом списке 1С при установке отбора?

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

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

Почему стандартный отбор не скрывает иерархию?

Разберем причину такого поведения платформы. Когда у динамического списка заполнено свойство ОсновнаяТаблица и включен режим просмотра «Дерево» или «Иерархический список», система ориентируется на структуру метаданных. Стандартный механизм отбора работает как фильтр содержимого: он определяет, какие именно записи (листья и узлы) должны быть выведены, но не перестраивает саму структуру дерева. Если папка существует в базе, платформа считает своим долгом показать её, даже если внутри неё все элементы скрыты фильтром. Чтобы изменить это поведение, нам придется вмешаться в настройки динамического списка более глубоко.

Решение 1: Использование свойства «Родитель верхнего уровня»

Проанализируем ситуацию, когда нам нужно ограничить просмотр одной конкретной веткой. Для этого у динамического списка существует стандартное свойство РодительВерхнегоУровня (в программном коде — ParentOfTopLevel). Это свойство указывает платформе, какой элемент следует считать «корнем» для построения дерева.

Как это применить:

Если в вашем коде установлено условие Родитель = &ВыбранныйКаталог, и вы хотите, чтобы дерево начиналось именно с этого каталога (без отображения пустых папок выше него), используйте следующий подход:


// В обработчике события или при изменении фильтра
Элементы.Список.РодительВерхнегоУровня = ВыбранныйКаталог;

Важный нюанс: Этот метод идеально подходит, если корень дерева один. Если же ваш отбор должен показать несколько папок из разных веток, этот параметр не поможет, так как он принимает только одну ссылку.

Решение 2: Программное изменение режима просмотра

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

Выясним, как это реализовать программно:


Если ЗначениеЗаполнено(ВыбранныйКаталог) Тогда
    Элементы.Список.Отображение = ОтображениеТаблицы.Список;
Иначе
    Элементы.Список.Отображение = ОтображениеТаблицы.Дерево;
КонецЕсли;

Это «честное» решение, которое не вводит пользователя в заблуждение пустыми папками и позволяет быстро увидеть результат выборки.

Решение 3: Управление свойством «Основная таблица»

Это более продвинутый метод. Если динамический список имеет заполненное поле ОсновнаяТаблица, платформа берет на себя управление иерархией. Если же это свойство очистить, список превращается в обычный набор данных, полученный запросом. При этом дерево будет строиться только на основе тех записей, которые реально попали в результат запроса.

Проанализируем шаги:

  1. В настройках динамического списка в конфигураторе оставьте поле ОсновнаяТаблица пустым (или очищайте его программно).
  2. В тексте запроса напишите условие получения данных.
  3. Включите иерархию через настройки компоновки данных (СКД) внутри динамического списка.

В этом случае СКД «схлопнет» пустые группы, так как они просто не попадут в выборку запроса.

Решение 4: Ограничение через RLS (Record Level Security)

Рассмотрим вариант, предложенный участниками форума. Если справочник небольшой (до 5 000 – 10 000 элементов), можно использовать механизм ограничений на уровне записей. Это позволяет «отрезать» ненужные ветки еще на уровне СУБД.

Разберем пример реализации:

  1. Создаем параметр сеанса РазрешенныеГруппы (тип Массив или ФиксированныйМассив).
  2. При установке фильтра заполняем этот параметр ссылками на группы, которые не являются пустыми.
  3. В роли пользователя прописываем условие RLS:

ГДЕ (НЕ ЭтоГруппа) 
ИЛИ (ЭтоГруппа И Ссылка В (&РазрешенныеГруппы))

Внимание: Будьте осторожны с использованием оператора ИЛИ в запросах RLS на больших таблицах — это может привести к значительному снижению производительности при прокрутке списка.

Решение 5: Метод «Массив ссылок» (сложный запрос)

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

Алгоритм действий:

  1. Выполняем предварительный запрос, который выбирает все элементы по вашему условию.
  2. Для найденных элементов собираем всех их родителей по всей цепочке вверх до корня.
  3. Помещаем все найденные ссылки (и элементы, и их родителей) в массив.
  4. Устанавливаем в динамическом списке параметр &МассивСсылок и используем условие ГДЕ Ссылка В (&МассивСсылок).

Пример части запроса для динамического списка:


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

Этот метод гарантирует, что в дереве останутся только те «ветки», которые ведут к нужным нам данным.

Решение 6: Условное оформление (как крайний вариант)

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

Минусы метода:

Подведем итоги

Мы рассмотрели несколько способов борьбы с «пустой» иерархией. Выбор метода зависит от вашей задачи:

Помните, что динамический список — это мощный инструмент, но его «автоматическая» магия иерархии иногда требует ручной настройки для достижения качественного UX (User Experience).

← На главную