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