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