Как получить итог по колонке в Дереве Значений в 1С?

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

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

Рассмотрим подробнее, как устроена работа со встроенным методом подсчета итогов, какие нюансы необходимо учитывать при наличии иерархических уровней и почему в некоторых случаях метод возвращает 0 или Неопределено.

Штатный метод Итог() и его синтаксис

Для вычисления суммы по колонке используется метод Итог(), выносимый у коллекции строк дерева (ДеревоЗначений.Строки):

Синтаксис метода:

Итог(<Колонка>, <ВключатьПодчиненные>)

Разберем параметры подробнее:

  1. Колонка (обязательный) — определяет имя колонки (тип Строка), ее индекс (тип Число) или объект КолонкаДереваЗначений.
  2. ВключатьПодчиненные (необязательный, тип Булево) — определяет режим подсчета иерархии:
    • Ложь (по умолчанию) — суммируются значения только верхнего (корневого) уровня дерева строк.
    • Истина — в итоговую сумму включаются значения абсолютно всех строк всех подчиненных уровней.

Обязательное условие: описание типов колонки

Выясним причину, почему метод Итог() может возвращать 0 или Неопределено. Метод суммирует только те ячейки, которые имеют тип Число или могут быть к нему преобразованы.

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

Пример правильной инициализации колонки с типом Число:


ОписаниеТипаЧисло = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2));
ДеревоЗначений.Колонки.Добавить("Сумма", ОписаниеТипаЧисло);

Пример расчета итогов с иерархией

Посмотрим на практический пример создания многоуровневого дерева значений и расчета итоговых показателей с разным значением параметра ВключатьПодчиненные:


ДЗ = Новый ДеревоЗначений;
ДЗ.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(20, 2)));

Для Идн1 = 1 по 3 Цикл
    Строка1 = ДЗ.Строки.Добавить();
    Строка1.Сумма = Идн1 * 1000;
    
    Для Идн2 = 1 по 3 Цикл
        Строка2 = Строка1.Строки.Добавить();
        Строка2.Сумма = Идн2 * 100;
        
        Для Идн3 = 1 по 3 Цикл
            Строка3 = Строка2.Строки.Добавить();
            Строка3.Сумма = Идн3 * 10;
            
            Для Идн4 = 1 по 3 Цикл
                Строка4 = Строка3.Строки.Добавить();
                Строка4.Сумма = Идн4;
            КонецЦикла;
        КонецЦикла;
    КонецЦикла;
КонецЦикла;

// Сумма только по верхнему уровню (Строка1)
ИтогВерхнийУровень = ДЗ.Строки.Итог("Сумма", Ложь); 

// Сумма по всем элементам и подчиненным веткам
ИтогВсеУровни = ДЗ.Строки.Итог("Сумма", Истина); 

Сообщить("Итог по верхнему уровню = " + ИтогВерхнийУровень); // вернет 6 000
Сообщить("Итог по всем уровням = " + ИтогВсеУровни);       // вернет 8 502

Важные особенности и подвохи при работе с иерархией

Проанализируем две распространенные проблемы при расчете итогов в Дереве Значений:

  1. Риск удвоения итогов: Если в вашей логике заполнения дерева в родительские строки уже вычисляется и записывается сумма их дочерних элементов, вызов метода с параметром ВключатьПодчиненные = Истина приведет к математическому удвоению суммы. В таком случае нужно либо вызывать метод с параметром Ложь (суммируя только промежуточные итоги родительских строк первого уровня), либо суммировать только конечные элементы («листья»).
  2. Особенности тонкого клиента (Управляемые формы): Объект ДеревоЗначений недоступен на тонком клиенте. На форме используется реквизит с типом ДанныеФормыДерево, коллекция строк которого не имеет метода Итог(). Попытка вызвать метод на клиенте приведет к ошибке. Для расчета итога необходимо передать данные на сервер, сконвертировать их методом РеквизитФормыВЗначение() в объект ДеревоЗначений и выполнить расчет.
← На главную