Рассмотрим распространенную ситуацию при разработке отчетов на базе Системы Компоновки Данных (СКД). При наличии иерархии (например, План - Характеристика - Шаг) и дублировании детальных записей, расчет общих итогов на верхних уровнях группировки часто отрабатывает некорректно. Из-за присоединения детальных таблиц значения ресурсов могут дублироваться, и обычная функция Сумма выдает завышенный результат.
Для решения задачи на нижнем уровне разработчики часто применяют функцию ВычислитьВыражениеСГруппировкойМассив. Но при попытке свернуть итоги дальше до верхнего уровня (например, до "Плана") возникает ошибка: "Использование вложенных агрегатных функций не допускается". Платформа 1С строго запрещает напрямую оборачивать одну агрегатную функцию в другую (например, писать Сумма(Максимум(...))).
Разберем несколько способов, которые помогут нам корректно рассчитать итоги на всех уровнях иерархии, не нарушая архитектурные ограничения платформы.
Данная функция создана специально для обхода запрета на вложенные агрегаты. Однако, поскольку первый параметр функции передается как строка, при глубокой иерархии нам необходимо правильно задваивать (экранировать) кавычки во вложенных выражениях. Проанализируем пример из обсуждения, где необходимо посчитать сумму максимумов:
ВычислитьВыражениеСГруппировкойМассив("Сумма(Максимум(ВычислитьВыражениеСГруппировкойМассив(""Сумма(ФактСумма)"", ""ОбщаяХарактеристика,ВидПланаОбщейХарактеристики"")))", "План")
В этом примере внутреннее выражение полностью берется во внешние кавычки, а внутренние кавычки дублируются "". При многоуровневых вложенных расчетах потребуется экранирование двойными, затем четверными кавычками. Важно следить за синтаксисом, так как малейшая ошибка (например, пропущенная скобка или неверное количество кавычек) приведет к отказу формирования отчета.
Посмотрим на более изящный способ решения через настройки самой СКД. Вместо одной сложной формулы мы можем настроить разные правила вычисления ресурса для разных уровней группировки. На вкладке "Ресурсы" нужно добавить ресурс несколько раз и в колонке "Рассчитывать по..." указать конкретные группировки.
Максимум(Количество).
Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(Количество)", "Характеристика"))
Такой подход позволяет системе четко понимать, по каким правилам собирать итоги для каждого узла дерева, избегая сложных нагромождений с кавычками.
Методически наиболее правильный способ избежать задвоения итогов в 1С — это перенос логики соединения таблиц из запроса на уровень СКД. Выясним причину дублей: они чаще всего появляются в результате левых соединений в запросе (когда одной строке плана соответствует несколько шагов).
Разобьем основной запрос на два набора данных:
Количество.Затем на вкладке "Связи наборов данных" соединим их по полю Характеристика. При такой архитектуре СКД "понимает", что значение ресурса принадлежит левому набору данных. Система автоматически, без применения сложных формул, рассчитает итоги по "Плану" без дублирования, а обычная функция Сумма(Количество) отработает идеально на всех уровнях.
Если разделение наборов данных невозможно, попробуем вынести часть внутренних вычислений (например, получение значения для конкретной группировки) в Вычисляемые поля.
Создадим вычисляемое поле с нужной формулой для детальных записей, а затем на вкладке "Ресурсы" к этому новому полю применим простую агрегатную функцию Сумма(). Это часто позволяет обойти платформенное ограничение на вложенность и делает структуру настроек отчета более читаемой.