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