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

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

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

Выясним причину проблемы: особенности иерархии элементов

Проанализируем механику работы динамического списка в режиме иерархического просмотра. В платформе 1С существует два вида иерархии:

  1. Иерархия групп и элементов: в этом случае существуют специальные категории — папки (группы). Платформа при наложении отбора делает исключение для родительских папок, оставляя их видимыми в динамическом списке, чтобы пользователь мог развернуть структуру и увидеть отфильтрованные элементы.
  2. Иерархия элементов: в этом случае понятие «группа» отсутствует, а родительскими узлами выступают обычные элементы справочника. При установке отбора платформа применяет его ко всем записям без исключения.

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

Способы решения проблемы

Рассмотрим подробнее доступные варианты обхода этого архитектурного ограничения в зависимости от требуемого поведения интерфейса.

1. Программная смена текущего родителя (свойство ТекущийРодитель)

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

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


// Устанавливаем текущего родителя для таблицы формы
Элементы.СписокПодразделений.ТекущийРодитель = ВыбранноеПодразделение;

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

2. Включение в отбор всей цепочки предков

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

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

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

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

3. Переход в режим просмотра «Список»

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


// Переключаем режим просмотра динамического списка в плоский список
Элементы.СписокПодразделений.РежимПросмотра = РежимПросмотраСписка.Список;

4. Использование объекта ДеревоЗначений вместо динамического списка

Если отбор должен выводить строго отфильтрованную иерархию (например, выводить только выбранные ветки без показа остальных узлов), стандартный динамический список не подходит. В такой ситуации данные считывают запросом на сервере с помощью инструкции ИЕРАРХИЯ и загружают в реквизит формы с типом ДеревоЗначений.

Рассмотрим пример формирования такого дерева на сервере:


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

Запрос.УстановитьПараметр("МассивПодразделений", ВыбранныеПодразделения);
РезультатЗапроса = Запрос.Выполнить();

// Дерево значений загружается в реквизит формы
ЗначениеВРеквизитФормы(РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией), "ДеревоПодразделений");

Таким образом, мы разобрали причины скрытия подчиненных элементов при отборах в справочнике с иерархией элементов и изучили решения, применяемые на практике в разработке на платформе 1С.

← На главную