В процессе разработки отчетов на Системе Компоновки Данных (СКД) часто возникают задачи, требующие не стандартного, а условного расчета итогов. Рассмотрим распространенный случай: необходимо вычислить среднее значение по колонке, но с одним важным правилом. Если среди всех значений, по которым считается итог, есть хотя бы один ноль, то итоговое среднее тоже должно быть равно нулю. Если же нулей нет, то нужно рассчитать обычное среднее арифметическое. Разберем, как реализовать такую логику в ресурсах СКД, и проанализируем типичные ошибки новичков.
Давайте проанализируем исходную задачу и первоначальную попытку ее решения. Автор пытался написать в выражении ресурса следующую конструкцию:
ЕСЛИ Представление(Оценка) = 0 ТОГДА Среднее(Оценка) = 0 ИНАЧЕ Среднее(Оценка) КОНЕЦ ЕСЛИ
Эта попытка содержит сразу несколько фундаментальных ошибок, понимание которых — ключ к правильному использованию выражений в СКД.
ВЫБОР, а не ЕСЛИ. Правильная структура выглядит так: ВЫБОР КОГДА <Условие> ТОГДА <Выражение1> ИНАЧЕ <Выражение2> КОНЕЦ.Среднее(Оценка)=0 — это операция сравнения, которая вернет результат булевого типа: Истина или Ложь. Она не "присваивает" итоговому значению ноль. В отчете это проявилось как вывод слова "ДА", что логично, так как результат сравнения оказался истинным. В ресурсе мы должны просто вернуть нужное значение, например, 0 или результат функции Среднее(Оценка).Представление(Оценка) = 0 проверяет значение поля Оценка для каждой отдельной строки набора данных. Однако наша задача — проверить наличие нуля во всей группировке, по которой считается итог. Для этого нужно использовать агрегатные функции, которые оперируют набором записей, а не одной записью.Представление(). Не рекомендуется использовать эту функцию в математических расчетах. Она возвращает строковое представление значения, которое может зависеть от формата и настроек. Для вычислений всегда следует использовать исходные поля числовых типов.Поняв эти ошибки, мы можем перейти к правильным и эффективным способам решения задачи.
Это самое простое и лаконичное решение, которое было найдено в ходе обсуждения. Оно основано на логическом предположении, что если минимальное значение в наборе неотрицательных чисел равно нулю, значит, в этом наборе точно есть хотя бы один ноль.
В настройках отчета СКД перейдите на вкладку "Ресурсы", найдите нужное поле и для него в колонке "Выражение" напишите следующий код:
ВЫБОР
КОГДА МИНИМУМ(Оценка) = 0
ТОГДА 0
ИНАЧЕ Среднее(Оценка)
КОНЕЦ
Разберем по шагам, как это работает:
МИНИМУМ(Оценка). Она находит наименьшее значение "Оценки" среди всех записей текущей группировки.ВЫБОР возвращает значение 0, как и требовалось по задаче.ИНАЧЕ, которая вызывает стандартную агрегатную функцию Среднее(Оценка) для расчета среднего арифметического.Этот способ идеально подходит для задачи, так как он компактен, эффективен и использует стандартные агрегатные функции.
Существует альтернативный способ, который может показаться более понятным и лучше отражающим суть бизнес-логики. В СКД есть специальная агрегатная функция Любой(), которая возвращает Истина, если переданное в нее логическое выражение истинно хотя бы для одной записи в группировке.
Выражение для ресурса будет выглядеть так:
ВЫБОР
КОГДА Любой(Оценка = 0)
ТОГДА 0
ИНАЧЕ Среднее(Оценка)
КОНЕЦ
Принцип работы здесь еще более очевиден:
Функция Любой(Оценка = 0) буквально означает: "проверить, есть ли в текущей группировке хотя бы одна (любая) запись, где поле Оценка равно 0". Если есть — функция вернет Истина, и итогом будет 0. Если нет — вернет Ложь, и будет рассчитано среднее.
Для нашей задачи оба решения — с МИНИМУМ() и с Любой() — логически эквивалентны и дадут одинаковый результат. Выбор между ними — часто вопрос стиля кодирования и личных предпочтений.
Часто встречается и обратная задача: нужно посчитать среднее, но при этом проигнорировать нулевые значения, как будто их и не было. Стандартные агрегатные функции СКД (Среднее, Сумма, Количество) по умолчанию игнорируют значения NULL.
Чтобы добиться такого поведения, нужно на уровне набора данных (в запросе или в вычисляемом поле) заменить нули на NULL. Создайте вычисляемое поле, например, ОценкаДляСреднего, со следующим выражением:
ВЫБОР
КОГДА Оценка = 0
ТОГДА NULL
ИНАЧЕ Оценка
КОНЕЦ
После этого на вкладке "Ресурсы" для расчета среднего вам будет достаточно использовать простую агрегатную функцию:
Среднее(ОценкаДляСреднего)
В этом случае при расчете среднего все записи, где оценка была равна нулю, будут полностью проигнорированы.
Подведем итог. Для реализации условных вычислений в ресурсах СКД используйте конструкцию ВЫБОР КОГДА и агрегатные функции (МИНИМУМ, МАКСИМУМ, ЛЮБОЙ), чтобы проанализировать весь набор данных в группировке. Это позволяет создавать гибкие и мощные отчеты, отвечающие сложным бизнес-требованиям.