При разработке сложных отчетов в системе компоновки данных (СКД) 1С часто возникает задача «двойной агрегации». Типичный пример: в отчете выводятся документы реализации и связанные с ними заказы. Нам необходимо найти максимальное количество в рамках каждой реализации, а затем получить общую сумму этих максимумов в поле «Итого». Стандартная настройка ресурса Сумма(Количество) в таких случаях выдаст неверный результат, так как просто сложит все строки, не учитывая логику выбора максимального значения для каждого документа.
В этой статье мы подробно разберем, как решить эту задачу с помощью встроенных функций языка выражений СКД, проанализируем нюансы работы с пользовательскими макетами и выясним, как избежать типичных ошибок при расчете итогов.
Представим ситуацию, когда данные в наборе записей выглядят следующим образом:
Если мы хотим сгруппировать данные по «РТУ» и получить сумму максимумов, расчет должен быть следующим:
Проблема заключается в том, что если в отчет выводится группировка «Заказ», СКД начинает суммировать все детальные записи, и стандартные средства агрегации не позволяют «перескочить» через уровень иерархии без специальных функций.
Наиболее эффективным и гибким способом решения этой задачи является использование функции ВычислитьВыражениеСГруппировкойМассив. Эта функция позволяет СКД сначала собрать данные в массив, применив к ним определенную группировку и агрегатную функцию, а затем выполнить финальное действие над этим массивом (например, суммирование).
Разберем синтаксис формулы, которую необходимо прописать в поле «Выражение» на закладке «Ресурсы»:
Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(Количество)", "ДокументРТУ"))
Рассмотрим подробнее, как работает эта конструкция:
Часто программисты сталкиваются с тем, что сложные формулы ресурсов перестают работать, если в отчете используется не автоматическая генерация макета, а собственный макет, созданный на закладке «Макеты». Выясним причину этого поведения.
Когда мы создаем свой макет, мы вручную связываем ячейки таблицы с параметрами. Для того чтобы расчет через ВычислитьВыражениеСГруппировкойМассив прошел успешно, необходимо соблюдать следующие правила:
Проанализируем ситуацию, когда в данных могут встречаться пустые значения (NULL). В системе 1С функция Максимум при работе с NULL ведет себя корректно, однако при суммировании элементов массива наличие неопределенных данных может привести к ошибкам в итоговом результате. Для обеспечения отказоустойчивости отчета рекомендуется модифицировать формулу:
Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(ЕстьNull(Количество, 0))", "ДокументРТУ"))
Использование ЕстьNull внутри агрегатной функции гарантирует, что в массив попадут только числовые значения, и итоговая сумма будет рассчитана математически верно даже при отсутствии части данных.
Иногда задачу можно решить еще до передачи данных в СКД — непосредственно в тексте запроса. Этот метод полезен, если объем данных очень велик, и формирование огромных массивов в памяти СКД замедляет отчет. Рассмотрим пример такого запроса:
ВЫБРАТЬ
ВложенныйЗапрос.СсылкаРТУ,
МАКСИМУМ(ВложенныйЗапрос.Количество) КАК МаксКолВо
ПОМЕСТИТЬ ВТ_Максимумы
ИЗ
(ВЫБРАТЬ
Т.ДокументРТУ КАК СсылкаРТУ,
Т.Количество КАК Количество
ИЗ
ДанныеДокументов КАК Т) КАК ВложенныйЗапрос
ГРУППИРОВАТЬ ПО
ВложенныйЗапрос.СсылкаРТУ
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
СУММА(ВТ_Максимумы.МаксКолВо) КАК ИтоговоеКоличество
ИЗ
ВТ_Максимумы КАК ВТ_Максимумы
Однако у этого метода есть существенный недостаток: если пользователю потребуется детализация по заказам внутри реализации в этом же отчете, «свернутые» данные в запросе не позволят этого сделать. Поэтому использование функций СКД в ресурсах является более предпочтительным для интерактивных отчетов.
Важно помнить, что функция ВычислитьВыражениеСГруппировкойМассив выполняет вычисления в оперативной памяти на стороне сервера 1С. Посмотрим, к чему это может привести на больших объемах:
Для оптимизации таких отчетов старайтесь ограничивать выборку данных параметрами (период, организация) и не использовать сложные вложенные функции без реальной необходимости. Если же отчет стабильно работает на ваших объемах данных, то решение через ресурсы СКД является наиболее элегантным и правильным с точки зрения архитектуры платформы 1С:Предприятие 8.
Мы проанализировали механизм расчета суммы максимальных значений в СКД. Подведем итоги:
Сумма(ВычислитьВыражениеСГруппировкойМассив(...)).NULL через ЕстьNULL.Следуя этим рекомендациям, вы сможете создавать точные и гибкие управленческие отчеты, корректно обрабатывающие сложные иерархические данные.