При разработке отчетов на базе системы компоновки данных (СКД) разработчики часто сталкиваются с ситуацией, когда необходимо сложить показатели разных строк на уровне группировки и при выполнении условия (например, если сумма равна нулю) скрыть строку из отчета. Однако при попытке реализовать это через обычные вычисляемые поля результат оказывается некорректным.
Проанализируем причины такого поведения платформы 1С и разберем по шагам правильные способы расчета и фильтрации данных.
Разберем механику работы платформы. В СКД существует четкое разделение этапов расчета:
Сумма1 + Сумма2 сначала рассчитается для каждого регистратора отдельно, а затем полученные результаты просто просуммируются платформой на уровне вышестоящей группировки.WHERE к исходным строкам до момента их свертки в группы. Если наложить отбор на уровне детальных строк, платформа исключит их из выборки до подсчета общих итогов, что полностью исказит финальный результат.Рассмотрим основной и самый надежный способ получения итоговой суммы двух полей на уровне группировки:
Сумма3.
Сумма(Сумма1) + Сумма(Сумма2)
Если расчет данного выражения требуется только для конкретной группировки (например, Заказ), в колонке Рассчитывать по... укажем именно эту группировку, а для детальных записей и общего итога оставим стандартный расчет или оставим поле пустым.
Чтобы скрыть строки, где итоговая сумма равна нулю, выполним настройку отбора:
Заказ.Сумма3 Не Равно 0.Только к группировке или К группировке и иерархии.При таком подходе СКД применит фильтр по аналогии с секцией HAVING в SQL — то есть отфильтрует уже рассчитанные итоги группировки, не искажая исходные детальные записи.
Если требуется получить значение агрегата на уровне группировки внутри вычисляемого поля или использовать его в сложных условиях, воспользуемся встроенными функциями языка выражений СКД:
Вычислить() позволяет рассчитать агрегатное выражение в контексте заданной группировки:
Вычислить("Сумма(Сумма1) + Сумма(Сумма2)", "Заказ")
ВычислитьГруппировкойМассив() полезна при необходимости собрать массив значений подчиненных строк для последующей обработки агрегатными функциями платформы.Если логика фильтрации слишком сложна для стандартных настроек компоновки, вывод данных можно перехватить программно в модуле объекта отчета:
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабличныйДокумент);
ПроцессорВывода.НачатьВывод();
Пока Истина Цикл
ЭлементРезультата = ПроцессорКомпоновки.Следующий();
Если ЭлементРезультата = Неопределено Тогда
Прервать;
КонецЕсли;
// Проверяем тип элемента и значение параметров группировки
// При необходимости пропускаем вызов ПроцессорВывода.ВывестиЭлемент()
ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
КонецЦикла;
ПроцессорВывода.ЗакончитьВывод();
Часто возникает ситуация: разработчик добавляет ресурс Сумма(Сумма1) + Сумма(Сумма2) и настраивает отбор в конфигураторе, но в режиме «1С:Предприятие» отчет продолжает работать по-старому. Выясним причину этой проблемы.
При открытии отчета платформа автоматически загружает последние сохраненные пользовательские настройки. В них сохранена старая структура колонок, ресурсов и условий отбора. Новые ресурсы и измененные группировки из схемы компоновки данных не вступают в силу автоматически.
Для того чтобы новые формулы и отборы применились, в пользовательском режиме необходимо сбросить параметры отчета к исходным: нажать Еще → Стандартные настройки (или перевыбрать стандартный вариант отчета).