Почему в динамическом списке 1С при отборе не скрываются помеченные на удаление группы и как это исправить?

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

При разработке интерфейсов на управляемых формах часто возникает задача отобразить иерархический справочник в виде дерева с исключением неактуальных данных. Типичный сценарий: на динамический список накладывается стандартный отбор ПометкаУдаления = Ложь, а для таблицы формы выбирается режим отображения «Дерево». При таком подходе неактуальные элементы действительно пропадают из списка, однако помеченные на удаление группы (папки) продолжают отображаться в дереве, оставаясь визуально пустыми. Разберем, почему платформа ведет себя именно так и какими способами можно добиться требуемого результата.

Причины платформенного поведения динамического списка

Проанализируем механику работы динамического списка в иерархических режимах («Дерево» и «Иерархический список»). Поведение, при котором отборы не влияют на группы (записи с признаком ЭтоГруппа = Истина), заложено разработчиками платформы «1С:Предприятие» намеренно.

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

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

Способ 1. Настройка условного оформления таблицы

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

Разберем по шагам, как настроить скрытие программно при открытии формы:

  1. Перейдем в модуль формы и найдем обработчик ПриСозданииНаСервере.
  2. Добавим элемент условного оформления для динамического списка.
  3. Зададим условие: отбираем строки, где ПометкаУдаления Равно Истина и ЭтоГруппа Равно Истина.
  4. В параметрах оформления установим свойство Видимость в значение Ложь.

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


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

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

Способ 2. Переключение таблицы в режим плоского списка

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

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

Способ 3. Разделение интерфейса на группы и элементы

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

  1. Левая панель: дерево, отображающее исключительно группы справочника (папки).
  2. Правая панель: динамический список, отображающий только элементы текущей выбранной группы.

Для правой панели стандартный отбор ПометкаУдаления = Ложь работает без сбоев, поскольку там отображаются только элементы. Для левой панели можно использовать динамический список с фиксированным отбором ЭтоГруппа = Истина и ПометкаУдаления = Ложь в режиме плоского списка или настроить собственную выборку.

Способ 4. Использование реквизита формы типа «ДеревоЗначений»

Если требуется строгое построение дерева без пустых или помеченных на удаление групп, стандартный динамический список не подойдет из-за архитектурных ограничений платформы. В таком случае заменим динамический список объектом ДеревоЗначений.

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

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

Посмотрим на пример серверной процедуры заполнения дерева:


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

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

← На главную