Как скрыть пустые группы в форме выбора 1С?

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

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

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

Почему динамический список показывает пустые группы?

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

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

Способ №1: Переключение в режим плоского списка

Это самое простое и эффективное решение, если сохранение древовидной структуры не является критически важным для пользователя. Как только мы переводим таблицу в режим списка, иерархические связи перестают влиять на видимость строк. Группы начинают обрабатываться как обычные объекты: если группа не подходит под фильтр — она исчезает.

Рассмотрим пример кода, который позволяет переключить режим отображения программно при открытии формы или изменении параметров:


// В обработчике ПриСозданииНаСервере или при изменении параметров отбора
Элементы.Дерево.Отображение = ОтображениеТаблицы.Список;

Проанализируем ситуацию: в этом случае Дерево (наименование элемента формы с типом ДинамическийСписок) перестает группировать данные. Пользователь увидит только те элементы и группы, которые напрямую соответствуют заданным условиям. Это «дешевый» способ с точки зрения ресурсов системы.

Способ №2: Использование условного оформления

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

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


Если Параметры.Отбор.Свойство("Родитель") Тогда
    Родитель = Параметры.Отбор.Родитель;
    
    // 1. Устанавливаем режим списка для корректной фильтрации
    Элементы.Дерево.Отображение = ОтображениеТаблицы.Список;
    
    // 2. Настраиваем отбор самого динамического списка
    ЭлементОтбора = Дерево.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Ссылка");
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВИерархии;
    ЭлементОтбора.Использование = Истина;
    ЭлементОтбора.ПравоеЗначение = Родитель;
    
    // 3. Настраиваем условное оформление для скрытия лишних групп
    ЭлементОформления = Дерево.УсловноеОформление.Элементы.Добавить();
    ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Видимость", Ложь);
    
    // Используем группу "НЕ", чтобы скрыть всё, что не входит в нужную иерархию
    УслОформГруппаНЕ = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
    УслОформГруппаНЕ.Использование = Истина;
    УслОформГруппаНЕ.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаНе;
    
    УслОформПоГруппе = УслОформГруппаНЕ.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    УслОформПоГруппе.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Ссылка");
    УслОформПоГруппе.ВидСравнения = ВидСравненияКомпоновкиДанных.ВИерархии;
    УслОформПоГруппе.ПравоеЗначение = Родитель;
КонецЕсли;

В данном примере мы комбинируем фильтрацию данных и визуальное скрытие. Обратите внимание на использование ВидСравненияКомпоновкиДанных.ВИерархии. Это позволяет эффективно работать с вложенными структурами справочника.

Способ №3: Модификация запроса динамического списка

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

Выясним причину сложности: нам нужно проверить наличие хотя бы одного элемента в группе, удовлетворяющего условиям. Сделать это «в лоб» через ГДЕ невозможно. Посмотрим на алгоритм реализации:

  1. Создаем запрос, который выбирает все ссылки элементов, подходящих под ваши условия.
  2. С помощью конструкции В ИЕРАРХИИ или соединений определяем список всех родительских групп для этих элементов.
  3. Передаем полученный массив ссылок (элементы + их родители) в параметр отбора динамического списка.

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

Способ №4: Полный отказ от динамического списка (Дерево значений)

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

Рассмотрим основные этапы реализации этого подхода:

  1. Создаем на форме реквизит с типом ДеревоЗначений.
  2. На сервере формируем запрос к справочнику, учитывая все необходимые фильтры.
  3. Программно обходим результат запроса и заполняем дерево.
  4. Если при заполнении мы видим, что у группы нет подчиненных узлов, мы просто не добавляем эту группу в дерево или удаляем её.

Хотя этот метод требует написания «не двух строчек кода», он дает абсолютный контроль над визуализацией. Вы сами решаете, какая папка будет видна, а какая — нет.

Резюме и рекомендации

Подведем итог нашему анализу:

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

← На главную