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