Как скрыть неактуальные элементы и группы в динамическом списке 1С

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

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

Анализ проблемы иерархии в динамических списках

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

Способ 1: Программная установка отбора в динамическом списке

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

Разберем пример кода, который устанавливает фильтр по реквизиту НеАктуальная:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Используем типовой механизм БСП для установки отбора
    ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(
        Список,                // Наш динамический список
        "НеАктуальная",       // Имя поля
        Ложь,                  // Значение (показывать только те, где Ложь)
        ВидСравненияКомпоновкиДанных.Равно,
        "Только актуальные",   // Представление для пользователя
        Истина                 // Использование
    );

КонецПроцедуры

Проанализируем этот метод: он хорошо работает для плоских списков. Однако в иерархических справочниках важно убедиться, что реквизит НеАктуальная заполнен и для групп, и для элементов. Если группа помечена как НеАктуальная = Истина, она должна скрыться. Если этого не происходит, проверьте настройки самого динамического списка — иногда включен режим отображения «Все уровни», который игнорирует некоторые фильтры для узлов дерева.

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

Как выяснилось в ходе обсуждения на форуме, в современных версиях платформы 8.3 отлично работает метод через Условное оформление. Это может показаться необычным, так как исторически условное оформление отвечало за цвета и шрифты, но свойство Видимость позволяет физически скрыть строку из интерфейса.

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


&НаСервере
Процедура СкрытьНеактуальныеЧерезОформление()
    
    ЭлементОформления = Список.УсловноеОформление.Элементы.Добавить();
    
    // Устанавливаем само оформление: Видимость = Ложь
    ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Видимость", Ложь);
    
    // Задаем условие: НеАктуальная = Истина
    ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("НеАктуальная");
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    ЭлементОтбора.ПравоеЗначение = Истина;
    
    // Применяем ко всей строке
    ЭлементОформления.Использование = Истина;

КонецПроцедуры

Важный нюанс: Этот способ скрывает данные на стороне клиента. Если записей очень много (десятки тысяч), динамический список все равно будет подгружать их с сервера, что может незначительно влиять на производительность. Однако с точки зрения визуального результата — это один из самых надежных способов «схлопнуть» ненужные группы.

Способ 3: Переход к произвольному запросу

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

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


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

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

Способ 4: Работа с «Фиксированными настройками»

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

Пример программной установки:


ЭлементОтбора = Список.ФиксированныеНастройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("НеАктуальная");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Ложь;

Проблема пустых групп (сложный случай)

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

Рассмотрим варианты решения:

  1. Автоматическая актуализация папок: При записи элемента проверять всех соседей по родителю. Если все стали неактуальными — помечать группу. Это требует написания логики в модуле объекта.
  2. Сложный запрос в динамическом списке: Использовать коррелированный подзапрос в секции ГДЕ, который проверяет наличие хотя бы одного актуального потомка. Внимание: это может существенно замедлить открытие формы справочника.
  3. RLS (Row Level Security): Ограничение на уровне записей. Это максимально надежный, но сложный в настройке и нагрузочный метод, который полностью исключает данные из всех запросов для текущего пользователя.

Резюме

Для большинства задач в 1С 8.3 оптимальным решением будет комбинация произвольного запроса (для скорости) и фиксированных настроек отбора (для надежности). Если же вам нужно быстро скрыть элементы в уже существующей форме без изменения структуры запроса, используйте условное оформление с параметром Видимость = Ложь. Мы надеемся, что эти методы помогут вам сделать интерфейс ваших решений более удобным и понятным для пользователей.

← На главную