При проектировании структуры справочников разработчики нередко сталкиваются с ситуацией, когда стандартный вид иерархии работает не так, как ожидалось. Например, требуется создать структуру, в которой элементы могут выступать родителями для других элементов или одновременно выполнять роль условных папок. Разберем по шагам особенности работы механизмов иерархии в платформе 1С, выясним причины ограничений и рассмотрим практические пути реализации требуемого поведения.
Проанализируем, как платформа 1С:Предприятие обрабатывает различные типы иерархии на уровне базы данных:
HierarchyFoldersAndItems): Данный режим строго разделяет записи на две категории — папки (группы) и конечные элементы. В качестве родителя для любого объекта (будь то группа или элемент) может выступать только группа. Элемент не может содержать внутри себя другие элементы или группы. На уровне СУБД платформа создает две физические таблицы: таблицу групп и таблицу элементов. По этой причине связать элемент с другим элементом в качестве родителя технически невозможно.HierarchyItems): В этом режиме сущность «Группа» отсутствует вовсе. Все записи являются элементами, и любой элемент может выступать родителем для другого элемента. В базе данных создается единая таблица, где поле Родитель ссылается на эту же таблицу.Посмотрим на важное предостережение: если вы решите изменить вид иерархии с «Иерархия групп и элементов» на «Иерархию элементов» в рабочей конфигурации, при реструктуризации базы данных все ранее созданные группы будут безвозвратно удалены вместе с нарушением связей подчиненности. Перед подобными изменениями обязательно выгружайте данные и переносите подчиненные элементы в корень.
Прежде чем переделывать структуру справочника, проверим типовые причины, из-за которых дерево или иерархический список могут отображаться как плоский список:
Отображение таблицы динамического списка на форме. Если установлено значение Список, иерархия скрывается. Для отображения дерева необходимо установить значение Иерархический список или Дерево (значения системного перечисления РежимОтображенияСписка).ОБЪЕДИНИТЬ / ОБЪЕДИНИТЬ ВСЕ, группировок СГРУППИРОВАТЬ ПО, а также при сложных подзапросах и соединениях, не позволяющих платформе однозначно связать поле Ссылка с полем Родитель.Рассмотрим наиболее популярный и универсальный способ: переключение справочника в режим «Иерархия элементов» с программным контролем поведения условных папок.
Разберем по шагам последовательность действий:
ЭтоКатегория (или ЗапретитьВыбор).ЭтоКатегория равен Истина (например, выделяем их жирным шрифтом или особым цветом текста).Посмотрим на пример кода в модуле формы списка/выбора:
&НаКлиенте
Процедура СписокПередОбработкойВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
ТекущиеДанные = Элемент.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено И ТекущиеДанные.ЭтоКатегория Тогда
СтандартнаяОбработка = Ложь;
ПоказатьПредупреждение(, "Выбор категорий запрещен! Выберите конечный элемент.");
КонецЕсли;
КонецПроцедуры
Если логика работы со справочником требует сложного нестандартного объединения разных типов данных в единую структуру, динамический список можно заменить на реквизит формы с типом ДеревоЗначений. В этом случае данные считываются запросом на сервере с использованием иерархических итогов.
Рассмотрим пример серверной процедуры заполнения дерева:
&НаСервере
Процедура ЗаполнитьДеревоНаСервере()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Спр.Ссылка КАК Ссылка,
| Спр.Наименование КАК Наименование,
| Спр.Родитель КАК Родитель
|ИЗ
| Справочник.Номенклатура КАК Спр
|ИТОГИ ПО
| Родитель ИЕРАРХИЯ";
РезультатЗапроса = Запрос.Выполнить();
ДеревоРезультат = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
ЗначениеВРеквизитФормы(ДеревоРезультат, "ДеревоЭлементов");
КонецПроцедуры
Проанализируем еще одну архитектурную схему: создание двух отдельных справочников — «Категории» (папки) и «Элементы». На форме списка создаются две таблицы: слева размещается дерево категорий, а справа — элементы, отфильтрованные по текущей выбранной категории слева. Такой подход исключает смешивание разнородных сущностей в одной таблице базы данных и обеспечивает высокую производительность при больших объемах данных.