ДеревоЗначений — один из самых коварных объектов. Оно идеально для визуализации иерархии, но при неправильном подходе превращает интерфейс в «тыкву». Главная проблема — сериализация: при каждом серверном вызове дерево гоняется целиком. Если в нем 100 000 строк, интерфейс «умрет». Разберем, как заставить его летать.

  1. Ленивая загрузка (Lazy Loading) — Технически верно

Чтобы дерево открывалось мгновенно, подгружайте данные только при развертывании узла.

Шаг 1: Создаем маркер-пустышку (Сервер)

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

bsl
// На сервере при заполнении уровня (инициализация корня)
НоваяСтрока = КоллекцияВерхнегоУровня.Добавить();
НоваяСтрока.Наименование = "Группа товаров";
Если Выборка.ЭтоГруппа Тогда
    // ПРАВИЛЬНО: Добавляем пустую подчиненную строку-маркер. 
    // Платформа увидит Количество() > 0 и нарисует "+" у узла.
    НоваяСтрока.ПолучитьЭлементы().Добавить(); 
КонецЕсли;

Шаг 2: Обработка события (Клиент)

Используем штатное событие таблицы ПередРазворачиванием(Элемент, Строка, Отказ). Параметр Строка здесь — это идентификатор (Число).

bsl
&НаКлиенте
Процедура ДеревоПередРазворачиванием(Элемент, Строка, Отказ)
    Узел = ДеревоДанных.НайтиПоИдентификатору(Строка);
    Дочерние = Узел.ПолучитьЭлементы();
    
    // ПРОВЕРКА: Если там только наша "пустышка" (одна строка без данных)
    Если Дочерние.Количество() = 1 И Дочерние.Ссылка.Пустая() Тогда
        ПодгрузитьДанныеНаСервере(Строка);
    КонецЕсли;
КонецПроцедуры


Шаг 3: Дозагрузка данных (Сервер)

bsl
&НаСервере
Процедура ПодгрузитьДанныеНаСервере(ИдентификаторСтроки)
    РодительскийУзел = ДеревоДанных.НайтиПоИдентификатору(ИдентификаторСтроки);
    Коллекция = РодительскийУзел.ПолучитьЭлементы();
    
    Коллекция.Очистить(); // Удаляем маркер-пустышку
    
    Запрос = Новый Запрос("ВЫБРАТЬ Ссылка, Наименование, ЭтоГруппа ИЗ Справочник.Номенклатура ГДЕ Родитель = &Родитель");
    Запрос.УстановитьПараметр("Родитель", РодительскийУзел.Ссылка);
    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Выборка.Следующий() Цикл
        НоваяСтрока = Коллекция.Добавить();
        ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
        Если Выборка.ЭтоГруппа Тогда // Снова ставим маркер для следующего уровня
            НоваяСтрока.ПолучитьЭлементы().Добавить();
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры
  1. Рекурсия vs Итеративный обход (Стек)

Рекурсия — это красиво, но медленно и опасно (Stack Overflow). 1С тратит ресурсы на каждый вызов процедуры и управление стеком.

КАК НЕ НАДО, Если Деревозначений имеет большой объем(Рекурсия):

bsl
Процедура Обход(Строки)
    Для Каждого Стр Из Строки Цикл
        // Обработка...
        Если Стр.Строки.Количество() > 0 Тогда // Лишний вызов метода в каждой итерации
            Обход(Стр.Строки); // Рекурсивный вызов - ТОРМОЗИТ!
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Оптимальное (Итеративный обход через массив-стек):

Работает в 1.5–2 раза быстрее и никогда не упадет.

bsl
Процедура ОбходИтеративный(КорневыеСтроки)
    Стек = Новый Массив;
    Для Каждого Стр Из КорневыеСтроки Цикл Стек.Добавить(Стр); КонецЦикла;

    Пока Стек.Количество() > 0 Цикл
        ТекущаяСтрока = Стек[Стек.Количество() - 1];
        Стек.Удалить(Стек.Количество() - 1);

        // --- Полезная работа здесь ---

        Подчиненные = ТекущаяСтрока.Строки;
        Для Каждого Подч Из Подчиненные Цикл
            Стек.Добавить(Подч);
        КонецЦикла;
    КонецЦикла;
КонецПроцедуры
  1. Поиск: Забудьте про циклы

Метод НайтиСтроки(СтруктураОтбора, Истина) — это «черная магия» платформы на C++.

Почему это оптимально: платформа обходит дерево напрямую в памяти, не создавая объекты «Строка» в интерпретаторе 1С.
Когда НЕ использовать: если нужно искать 10 000 раз в цикле. В этом случае выгрузите дерево в ТаблицуЗначений, проиндексируйте её и ищите через ТЗ.Найти().

  1. Оптимизация через СКД

Если дерево — это сложный отчет с итогами, не собирайте его запросами в цикле:

Настройте СКД с иерархией группировок.
Используйте ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений.
СКД соберет дерево на уровне SQL и внутренних алгоритмов ядра, что в разы быстрее ручного заполнения.
Итоговый чек-лист производительности

ОперацияОшибка (Тормоза)Решение (Скорость)
ЗагрузкаВсе дерево сразуЛенивая загрузка + «Пустышка»
ОбходРекурсияЦикл Пока + Массив (Стек)
ПоискЦикл Для КаждогоНайтиСтроки(…, Истина)
ОформлениеСложные формулы И/ИЛИКолонка-индекс цвета

ДеревоЗначений — это визуальный объект, а не вычислительный. Считайте в таблицах или СКД, а пользователю отдавайте данные порциями через «Ленивую загрузку».

Словарь

Tree (дерево)Иерархическая структура данных в форме списка значений 1С — ноды с ветвями и листьями
ValueTreeДерево значений — объект платформы 1С для хранения иерархических данных
NodeУзел дерева — элемент иерархии в дереве значений
PerformanceПроизводительность — скорость обработки данных в дереве при большом количестве строк