Как правильно рассчитать общий итог в СКД при использовании сложных выражений и условных конструкций?

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

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

Рассмотрим, почему возникает эта проблема и как правильно настроить выражение ресурса в СКД, чтобы получить точные значения на всех уровнях отчета, включая общий итог.

Выясним причину возникновения проблемы

По умолчанию СКД рассчитывает значения ресурсов для всех верхних уровней группировок и общих итогов по детальным записям набора данных, а не путём простого суммирования уже рассчитанных итогов подчиненных группировок. Если на уровне отдельной номенклатуры мы обнуляем отрицательный остаток с помощью выражения:

ВЫБОР КОГДА Сумма(Ост) <= 0 ТОГДА 0 ИНАЧЕ Сумма(Ост) КОНЕЦ

то при расчете общего итога платформа сначала просуммирует детали по всему отчету. Если общая сумма остатков окажется положительной, условие ВЫБОР КОГДА не обнулит отрицательные позиции по отдельным номенклатурным позициям. В результате общий итог не совпадет со суммой строк отчета.

Решение с помощью функции ВычислитьВыражениеСГруппировкойМассив

Для корректного расчета итогов по вложенным группировкам используется функция языка выражений СКД ВычислитьВыражениеСГруппировкойМассив. Она позволяет сначала вычислить выражение для каждого элемента указанной группировки, сформировать массив полученных значений, а затем просуммировать их.

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

Разберем итоговое выражение для ресурса:


Сумма(ВычислитьВыражениеСГруппировкойМассив("ВЫБОР КОГДА Сумма(Ост) <= 0 ТОГДА 0 ИНАЧЕ Сумма(Ост) КОНЕЦ", "Регистратор, номенклатура"))

Указание строки "Регистратор, номенклатура" предписывает СКД вычислить выражение для каждой уникальной комбинации регистратора и номенклатуры, обнулить отрицательные значения на самом нижнем уровне и затем корректно сложить их для средних группировок и общего итога.

Альтернативные способы решения

Хотя использование функции ВычислитьВыражениеСГруппировкойМассив универсально, существуют и другие подходы к решению данной задачи:

  1. Перенос логики в запрос (рекомендуемый способ):

    Самый оптимальный вариант с точки зрения производительности — выполнить обнуление отрицательных остатков прямо в запросе набора данных (во временной таблице или вложенном запросе). Сгруппировав данные по номенклатуре и регистратору в запросе, вы получите поле, для которого в СКД достаточно будет прописать стандартное выражение Сумма(ИмяПоля) на всех уровнях.

  2. Разделение формул по колонке «Рассчитывать по…»:

    На вкладке Ресурсы в СКД можно добавить одно и то же поле несколько раз, указав разные выражения для конкретных группировок и общего итога в колонке Рассчитывать по…. Это делает логику расчета более наглядной и упрощает отладку.

Ограничения и нюансы работы с функцией

Проанализируем особенности поведения функции ВычислитьВыражениеСГруппировкойМассив, которые необходимо учитывать при разработке:

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