Как правильно выполнить постобработку дерева значений в 1С при выводе данных из запроса?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с отчетами или сложными формами в 1С часто возникает задача вывода данных в виде иерархического списка. Использование метода Выгрузить с параметром ОбходРезультатаЗапроса.ПоГруппировкамСИерархией позволяет быстро получить ДеревоЗначений, но часто требует «косметического» или логического ремонта. Давайте разберем, как эффективно доработать дерево значений и избавиться от лишних усилий.

Реализация рекурсивного обхода дерева значений

Одной из главных проблем при работе с деревом является необходимость обхода всех его уровней. Если структура данных динамическая, на помощь приходит рекурсия. Рассмотрим шаблон процедуры, которая позволит вам «пройтись» по каждой ветке дерева и выполнить необходимые преобразования (например, расчет итогов или изменение значений в ячейках).

Принцип работы заключается в том, что процедура вызывает саму себя для каждой вложенной строки, пока не дойдет до «листьев» дерева:


Процедура СделатьЧтотоСДеревомРекурсивно(ВеткаДерева)
    Для Каждого ТекущаяВеткаДерева Из ВеткаДерева.Строки Цикл
        Если ТекущаяВеткаДерева.Строки.Количество() > 0 Тогда
            // Если есть вложенные строки, идем глубже
            СделатьЧтотоСДеревомРекурсивно(ТекущаяВеткаДерева);
        Иначе 
            // Обрабатываем текущую ветку дерева (конечный узел)
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

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

Оптимизация структуры данных и удаление «воздуха»

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

  1. Работа на уровне запроса. Вместо того чтобы вычислять итоговые суммы в цикле, старайтесь использовать конструкцию ИТОГИ ПО в тексте запроса. Это позволит 1С самой рассчитать суммы для иерархических группировок, и они будут доступны вам сразу после выгрузки в ДеревоЗначений.
  2. Унификация полей. Если у вас разные типы документов (например, ПриходнаяНакладная и РасходнаяНакладная), используйте в запросе ВЫБОР КОГДА, чтобы привести суммы из разных колонок к одному полю, например, Сумма. Это избавит вас от необходимости писать сложные условия Если ТипЗнч(...) в коде.
  3. Программное удаление. Если колонки не нужны в интерфейсе, их можно удалить методом УдалитьКолонку() объекта ДеревоЗначений до помещения данных в реквизит формы.

Настройка отображения дерева в управляемой форме

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

Перейдите в свойства табличного поля, которое привязано к вашему дереву значений, и найдите свойство НачальноеОтображениеДерева. Установите его в значение РаскрыватьВсеУровни. Это избавит пользователя от необходимости вручную нажимать на «плюсики» для просмотра содержимого документа.

Разбор практического примера обработки строк

В случае, когда необходимо принудительно пересчитать суммы на верхнем уровне, как это обсуждалось в нашей дискуссии, можно использовать обход строк первого уровня. Рассмотрим пример, где мы аккумулируем стоимость товаров в разрезе документов:


Для Каждого СтрПервогоУровня из ПромДерево.Строки Цикл
    НовСтрока = Документы.ПолучитьЭлементы().Добавить();
    НовСтрока.Регистратор = СтрПервогоУровня.Регистратор;
    Сумма = 0;
    
    Для Каждого СтрВторогоУровня из СтрПервогоУровня.Строки Цикл
        Сумма = Сумма + СтрВторогоУровня.Сумма;
        // Заполняем вложенные данные
        НовСтрока2 = НовСтрока.ПолучитьЭлементы().Добавить();
        НовСтрока2.Номенклатура = СтрВторогоУровня.Номенклатура;
    КонецЦикла;
    
    НовСтрока.Сумма = Сумма;
КонецЦикла;

Важное примечание: Если вы замечаете «нулевой» уровень в дереве (лишняя итоговая строка), проверьте, не включены ли общие итоги в запросе. Их отключение в запросе или фильтрация после выгрузки — самый простой способ привести внешний вид дерева к желаемому состоянию. Работайте с данными осознанно, стараясь максимально перенести логику на этап выполнения запроса, и ваше дерево значений всегда будет компактным и быстрым.

← На главную