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