Как реализовать подчинение элементов элементам и настроить смешанную иерархию в справочнике 1С?

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

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

Архитектурные ограничения видов иерархии в платформе 1С

Проанализируем, как платформа 1С:Предприятие обрабатывает различные типы иерархии на уровне базы данных:

  1. Иерархия групп и элементов (HierarchyFoldersAndItems): Данный режим строго разделяет записи на две категории — папки (группы) и конечные элементы. В качестве родителя для любого объекта (будь то группа или элемент) может выступать только группа. Элемент не может содержать внутри себя другие элементы или группы. На уровне СУБД платформа создает две физические таблицы: таблицу групп и таблицу элементов. По этой причине связать элемент с другим элементом в качестве родителя технически невозможно.
  2. Иерархия элементов (HierarchyItems): В этом режиме сущность «Группа» отсутствует вовсе. Все записи являются элементами, и любой элемент может выступать родителем для другого элемента. В базе данных создается единая таблица, где поле Родитель ссылается на эту же таблицу.

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

Почему иерархия может не отображаться в форме списка?

Прежде чем переделывать структуру справочника, проверим типовые причины, из-за которых дерево или иерархический список могут отображаться как плоский список:

  1. Режим отображения таблицы: Проверим свойство Отображение таблицы динамического списка на форме. Если установлено значение Список, иерархия скрывается. Для отображения дерева необходимо установить значение Иерархический список или Дерево (значения системного перечисления РежимОтображенияСписка).
  2. Ограничения произвольного запроса в динамическом списке: Если в динамическом списке используется собственный текст запроса, иерархический просмотр отключается платформой при наличии операторов ОБЪЕДИНИТЬ / ОБЪЕДИНИТЬ ВСЕ, группировок СГРУППИРОВАТЬ ПО, а также при сложных подзапросах и соединениях, не позволяющих платформе однозначно связать поле Ссылка с полем Родитель.
  3. Установленные отборы: При установке фильтров по реквизитам динамический список может автоматически разворачиваться в линейный вид для вывода всех подходящих записей без учета структуры ветвей.

Решение 1: Иерархия элементов с флагом категории и запретом выбора

Рассмотрим наиболее популярный и универсальный способ: переключение справочника в режим «Иерархия элементов» с программным контролем поведения условных папок.

Разберем по шагам последовательность действий:

  1. В свойствах справочника в конфигураторе устанавливаем вид иерархии: Иерархия элементов.
  2. Добавляем в справочник реквизит булевого типа, например, ЭтоКатегория (или ЗапретитьВыбор).
  3. В форме списка настраиваем условное оформление для строк, у которых реквизит ЭтоКатегория равен Истина (например, выделяем их жирным шрифтом или особым цветом текста).
  4. В форме выбора и форме списка перехватываем попытку выбора такого элемента в документах, чтобы исключить подстановку папки-категории вместо конкретного элемента.

Посмотрим на пример кода в модуле формы списка/выбора:


&НаКлиенте
Процедура СписокПередОбработкойВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    ТекущиеДанные = Элемент.ТекущиеДанные;
    Если ТекущиеДанные <> Неопределено И ТекущиеДанные.ЭтоКатегория Тогда
        СтандартнаяОбработка = Ложь;
        ПоказатьПредупреждение(, "Выбор категорий запрещен! Выберите конечный элемент.");
    КонецЕсли;
КонецПроцедуры

Решение 2: Построение дерева через «ДеревоЗначений»

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

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


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

Решение 3: Разделение на два связанных справочника

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

← На главную