При разработке отчетов и обработок в конфигурациях 1С (например, 1С:Зарплата и Управление Персоналом) часто возникает задача сгруппировать вычисленные данные по определенному разрезу (например, по подразделению) и вывести промежуточные итоги по каждой группировке.
Рассмотрим распространенную ошибку, когда разработчик пытается получить иерархическую структуру с подитогами с помощью метода Свернуть() у таблицы значений, и разберем правильные способы решения этой задачи.
Объект ТаблицаЗначений в платформе 1С является плоской двумерной таблицей. В ней невозможно одновременно сохранить детальные записи и сформировать иерархические сворачиваемые группировки с подитогами.
Метод Свернуть() изменяет исходную таблицу значений: он удаляет дублирующиеся строки по указанным группировочным колонкам и суммирует данные в ресурсах. Синтаксис метода выглядит следующим образом:
ТаблицаЗначений.Свернуть("КолонкиГруппировки", "КолонкиСуммирования");
Разберем основные правила вызова метода:
СтатьяЗатрат или Подразделение) передавать во второй параметр **нельзя**.Проанализируем пример корректного вызова свертки:
// Корректная свертка по группировкам Подразделение и СтатьяЗатрат
ТаблицаЗначений.Свернуть("Подразделение, СтатьяЗатрат", "База, Резерв, Тридцать, НольШесть");
После вызова этого метода строка с одинаковым подразделением и статьей затрат станет единой, а числа в колонках База, Резерв и т.д. просуммируются. Однако детальные строки при этом исчезнут, и дерево с кнопками свертывания/разворачивания создано не будет.
Если на форме необходимо отобразить полноценное дерево с итогами по подразделениям и вложенными детальными строками (например, по статьям затрат), вместо ТаблицаЗначений следует использовать объект ДеревоЗначений.
Разберем алгоритм построения дерева через запрос:
ИТОГИ СУММА(...) ПО Подразделение.ДеревоЗначений с помощью метода Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам).Посмотрим на пример реализующего кода:
МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Текст =
"ВЫБРАТЬ
| ТЗ.Подразделение КАК Подразделение,
| ТЗ.СтатьяЗатрат КАК СтатьяЗатрат,
| ТЗ.База КАК База,
| ТЗ.Резерв КАК Резерв
|ПОМЕСТИТЬ ВТ_Данные
|ИЗ
| &ТаблицаДанных КАК ТЗ;
|
|ВЫБРАТЬ
| ВТ.Подразделение КАК Подразделение,
| ВТ.СтатьяЗатрат КАК СтатьяЗатрат,
| ВТ.База КАК База,
| ВТ.Резерв КАК Резерв
|ИЗ
| ВТ_Данные КАК ВТ
|ИТОГИ
| СУММА(База),
| СУММА(Резерв)
|ПО
| Подразделение";
Запрос.УстановитьПараметр("ТаблицаДанных", ТаблицаЗначений);
РезультатЗапроса = Запрос.Выполнить();
// Выгружаем данные в Дерево Значений с сохранением иерархии
ДеревоРезультат = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам);
В получившемся дереве на верхнем уровне будут находиться подразделения с общими суммами, а на нижнем — конкретные записи по статьям затрат.
Если задача выполняется в рамках отчета, наиболее эффективным решением будет использование Системы компоновки данных (СКД). СКД автоматически рассчитывает подитоги и строит группировки любой сложности.
Выясним причину, почему вычисляемые поля или поля запроса могут быть недоступны для группировки в настройках СКД:
КАК (например, Отражение.Сумма * 100 / 11 КАК ПроцентСуммы).Сумма(ПроцентСуммы)).Подразделение, а внутрь нее вложить детальные записи или группировку по СтатьяЗатрат.