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

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

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

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

Особенность работы агрегатной функции Минимум с NULL-значениями

Проанализируем распространенную ошибку: если написать в выражении ресурса конструкцию ВЫБОР КОГДА Поле >= 0 ТОГДА Поле ИНАЧЕ 0 КОНЕЦ, то при наличии отрицательных чисел они превратятся в нули, и функция Минимум() вернет 0 (если нет строго меньших положительных чисел). Если же в выборке есть нули, они также станут минимумом, что не решает задачу поиска минимального положительного значения.

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

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

Минимум(ВЫБОР КОГДА СуммаОстаток > 0 ТОГДА СуммаОстаток КОНЕЦ)

Выясним, как отрабатывает эта формула:

  1. Все строки, где СуммаОстаток <= 0, возвращают NULL.
  2. Агрегатная функция Минимум() отбрасывает NULL и находит минимальное значение только среди строго положительных чисел.
  3. Если во всей выборке группировки нет ни одного положительного числа, результатом вычисления будет NULL. При необходимости его можно обработать с помощью функции ЕСТЬNULL(..., 0).

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

Представим типовую структуру отчета: есть вышестоящая группировка (например, Группировка1 — Подразделение или Номенклатурная группа) и вложенная в нее Группировка2 (например, конкретная Номенклатура). Нам необходимо вывести на уровне каждой строки Группировка2 минимальное положительное значение по всей Группировка1 и посчитать разницу с текущей строкой.

Для обращения к итогам вышестоящих группировок в СКД применяется функция ВычислитьВыражение(). Разберем по шагам настройку такого расчета:

  1. Перейдем на вкладку Ресурсы.
  2. Для вычисления минимального положительного значения в контексте родителя напишем выражение:

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

Здесь первым параметром в кавычках передается само агрегатное выражение, а вторым параметром — имя группировки, в рамках которой нужно выполнить агрегацию. В результате в каждой строке Группировка2 будет доступно минимальное положительное значение родительской Группировка1.

Если нам требуется вывести разницу (отклонение текущего значения от минимума родительской группы), запишем формулу ресурса:


Ресурс - ВычислитьВыражение("Минимум(ВЫБОР КОГДА Ресурс > 0 ТОГДА Ресурс КОНЕЦ)", "Группировка1")

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

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

Посмотрим на решение с использованием агрегации по массиву с условием отбора:


Минимум(ВычислитьВыражениеСГруппировкойМассив("Сумма(Ресурс)", "Группировка2", "Сумма(Ресурс) > 0"))

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

  1. Выражение: "Сумма(Ресурс)" — агрегат, который рассчитывается для каждой вложенной группы.
  2. Поле группировки: "Группировка2" — разрез, по которому формируется массив значений.
  3. Отбор записей: "Сумма(Ресурс) > 0" — условие, отсекающее нулевые и отрицательные итоги.

Функция формирует массив только из положительных итогов дочерних строк, а внешняя функция Минимум() возвращает наименьший элемент массива. Чтобы транслировать этот результат внутрь дочерних строк, объединим функции:


ВычислитьВыражение("Минимум(ВычислитьВыражениеСГруппировкойМассив(""Сумма(Ресурс)"", ""Группировка2"", ""Сумма(Ресурс) > 0""))", "Группировка1")

Вариант реализации через «Вычисляемые поля»

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

  1. Откроем вкладку Вычисляемые поля и добавим новое поле, например РесурсТолькоПоложительный.
  2. В колонке Выражение укажем:

ВЫБОР КОГДА Ресурс > 0 ТОГДА Ресурс КОНЕЦ

  1. Перейдем на вкладку Ресурсы и настроим расчет:

Минимум(РесурсТолькоПоложительный)

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

Особенности настройки расчета в структуре «Таблица»

Когда отчет строится в виде перекрестной таблицы (строки и колонки), контекст вычислений меняется. Разберем нюансы настройки:

  1. Именование элементов структуры: На вкладке Настройки в свойствах строк и колонок таблицы обязательно зададим понятные системные имена (поле Имя в окне свойств элемента, например СтрокиНоменклатура и КолонкиСклады).
  2. Указание области расчета: В функциях ВычислитьВыражение и ВычислитьВыражениеСГруппировкойМассив в качестве контекста можно передавать имя группировки строк или колонок для выполнения расчета строго по горизонтали или вертикали таблицы:

Минимум(ВычислитьВыражениеСГруппировкойМассив("Сумма(Ресурс)", "СтрокиНоменклатура", "Сумма(Ресурс) > 0"))
  1. Колонка «Рассчитывать по...»: На вкладке Ресурсы можно продублировать поле ресурса и настроить разные формулы расчета для группировок строк, колонок и общих итогов таблицы, указав нужные разрезы в колонке Рассчитывать по....
← На главную