В практике разработки на платформе 1С:Предприятие 8.3 часто возникает задача отображения данных в виде дерева, где структура определяется не самим справочником, а его владельцем. Типичный пример: у нас есть иерархический справочник Подразделения и подчиненный ему справочник Сотрудники (или Оборудование). Нам необходимо вывести список так, чтобы сотрудники отображались внутри своих подразделений, при этом сами подразделения должны сохранять свою иерархическую структуру (вложенность цехов, отделов и участков).
Разберем подробно, как реализовать такую задачу, проанализируем стандартные возможности динамического списка и рассмотрим альтернативные методы решения.
Первый и самый простой способ — это использование встроенного механизма группировок компоновки данных, который интегрирован в динамический список. Рассмотрим пошагово, как это настроить:
ДинамическогоСписка и откроем настройки компоновки данных (ссылка Настройка компоновки данных).Владелец.Элементы выбрать значение Иерархия. Именно эта настройка заставляет систему анализировать иерархию справочника-владельца.Проанализируем ситуацию, которая часто возникает при такой настройке: если мы просто добавим группировку, платформа создаст дерево, где на первом уровне будут узлы владельца, а внутри — элементы подчиненного справочника. Однако, чтобы визуально это выглядело как единая структура, нужно убедиться, что свойство Отображение таблицы на форме установлено в значение Дерево или Иерархический список.
Иногда стандартные группировки не обеспечивают нужного визуального эффекта или работают слишком медленно. В таких случаях мы можем самостоятельно сконструировать дерево в тексте запроса динамического списка. Рассмотрим пример реализации, где мы объединяем данные двух справочников в одну выборку.
Для этого в запросе динамического списка мы создадим виртуальные поля, которые будут отвечать за связь "родитель-ребенок" для обоих справочников. Посмотрим на пример кода запроса:
ВЫБРАТЬ
Подразделения.Ссылка КАК СсылкаДляДерева,
Подразделения.Родитель КАК РодительДляДерева,
Подразделения.Наименование КАК Наименование,
ИСТИНА КАК ЭтоГруппа
ИЗ
Справочник.Подразделения КАК Подразделения
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
Сотрудники.Ссылка,
Сотрудники.Владелец,
Сотрудники.Наименование,
ЛОЖЬ
ИЗ
Справочник.Сотрудники КАК Сотрудники
После написания такого запроса выполним следующие действия:
РодительДляДерева является родителем для поля СсылкаДляДерева.Не определено, так как мы выбираем данные из разных таблиц. Стоит учитывать, что это отключит стандартные команды добавления элементов, и их придется прописывать программно.Отображение — Дерево.Важное замечание: При использовании ОБЪЕДИНИТЬ ВСЕ необходимо следить за уникальностью ключей. Если Ссылка из одного справочника совпадет по внутреннему идентификатору со ссылкой из другого (что маловероятно, но теоретически возможно при обмене данными), дерево может отобразиться некорректно. Для гарантии уникальности часто используют составные типы или дополнительные идентификаторы.
Если справочники очень большие и динамический список начинает "тормозить" при использовании иерархических группировок, программисты иногда прибегают к хитрости. Мы можем оставить список плоским, но добавить в него колонку, которая будет содержать отступы или иконки, имитирующие дерево.
Выясним причину популярности этого метода: он работает максимально быстро, так как СУБД не нужно выполнять рекурсивные запросы для построения дерева. Мы просто вычисляем Уровень() элемента в запросе и в зависимости от этого числа выводим нужное количество спецсимволов (неразрывных пробелов) перед наименованием.
Рассмотрим подробнее, почему механизм группировок в динамическом списке может работать медленно. Когда мы включаем Тип группировки = Иерархия, платформа генерирует сложные SQL-запросы с использованием конструкций WITH или временных таблиц для обхода дерева. Если в справочнике-владельце десятки тысяч элементов, каждое раскрытие узла может занимать время.
Чтобы оптимизировать работу, рекомендуем:
ГДЕ Ссылка В (ВЫБРАТЬ РАЗЛИЧНЫЕ Владелец ИЗ Справочник.Подчиненный)).Родитель и Владелец.ДинамическогоСписка.Таким образом, мы проанализировали основные подходы к созданию иерархии в динамическом списке. Для большинства стандартных задач достаточно правильно настроить Группировку с типом Иерархия в настройках компоновки данных, не забывая про установку свойства Отображение в значение Дерево у элемента формы.