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