1C-Code → Как сделать → Чем дерево значений отличается от таблицы значений
Тем же, чем оглавление от списка: у строки есть подчинённые строки. Колонки те же, обход другой — рекурсивный.
Дерево = Новый ДеревоЗначений;
Дерево.Колонки.Добавить("Наименование");
Дерево.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
Группа = Дерево.Строки.Добавить();
Группа.Наименование = "Материалы";
Позиция = Группа.Строки.Добавить(); // подчинённая строка
Позиция.Наименование = "Гвозди";
Позиция.Сумма = 500;
// обход — рекурсией
Процедура ОбойтиВетку(Строки)
Для Каждого Строка Из Строки Цикл
// ... работа со строкой ...
ОбойтиВетку(Строка.Строки); // и вглубь
КонецЦикла;
КонецПроцедуры
У таблицы значений строки добавляются прямо: ТЗ.Добавить(). У дерева — Дерево.Строки.Добавить(), и у каждой строки есть своя коллекция Строки. Отсюда и рекурсия при обходе.
Дерево не суммирует подчинённые строки автоматически. Либо считать при обходе снизу вверх, либо строить дерево из запроса с секцией ИТОГИ — тогда группы придут уже с итогами.
Результат.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам) вернёт дерево, если в запросе есть ИТОГИ ПО. Собирать его вручную в таком случае незачем.
Дерево нужно реже, чем кажется. Если иерархия нужна только для показа на форме, часто достаточно таблицы с колонкой уровня или группировки в СКД. Рекурсивный обход легко написать так, что он зациклится на данных с испорченной иерархией — а такие в базах встречаются.
Задача на это. Прочитать приём и применить его — разные умения. В тренажёре есть задача «Дерево из плоской таблицы»: собрать иерархию из плоской выгрузки: группы — корневыми строками, товары — подчинёнными им. Решение проверяется скрытыми тестами, в том числе на краевых случаях, о которых в условии не сказано.