在DevExpress报表ReportFooter中按产品统计总计遇问题求助
DevExpress报表按产品名称统计总和解决方案
问题根源
你手动在BeforePrint/AfterPrint事件累加的方式存在两个核心问题:
- 空引用错误:ReportFooter中的
xrLabel61初始值为空或未初始化,执行Convert.ToDouble(xrLabel61.Text)会抛出空引用异常。 - 事件时机错误:ReportFooter的BeforePrint/AfterPrint事件触发时,明细行的数据已经处理完成,
GetCurrentColumnValue无法获取到明细的PrecioTotal值;而如果在明细的BeforePrint事件里操作ReportFooter控件,控件可能还未实例化。
推荐解决方案:使用内置分组与汇总功能
DevExpress报表提供了原生的分组和汇总机制,无需手动写累加代码,更稳定可靠:
步骤1:按产品名称添加分组
- 打开报表设计器,选中DetailBand(明细带区)。
- 在属性面板中找到
GroupHeader属性,点击右侧的...按钮打开分组编辑器。 - 添加一个分组,设置分组字段为
ProductoNombre(产品名称字段),确定后会自动生成GroupHeaderBand和GroupFooterBand。
步骤2:在组页脚添加产品汇总
- 选中
GroupFooterBand,从工具箱拖入一个XRLabel控件。 - 选中该标签,在属性面板中找到
Summary属性:- 设置
Summary.Func为Sum(求和) - 设置
Summary.FieldName为PrecioTotal(要统计的字段) - 设置
Summary.Running为Group(仅在当前分组内汇总)
- 设置
- 可以给该标签设置显示文本,比如绑定
ProductoNombre字段,同时显示汇总值,表达式可写为:[ProductoNombre] + ' 总计: ' + [SummarySum(PrecioTotal)]
步骤3:在ReportFooter展示所有产品汇总(可选)
如果需要在ReportFooter集中展示各产品的总和,有两种方式:
- 方式1:使用自定义变量存储汇总值
- 在报表类中定义字典变量存储各产品的总和:
private Dictionary<string, double> productTotals = new Dictionary<string, double>(); - 在DetailBand的BeforePrint事件中累加:
string productName = GetCurrentColumnValue("ProductoNombre")?.ToString(); if (string.IsNullOrEmpty(productName)) return; double priceTotal = Convert.ToDouble(GetCurrentColumnValue("PrecioTotal")); if (productTotals.ContainsKey(productName)) { productTotals[productName] += priceTotal; } else { productTotals.Add(productName, priceTotal); } - 在ReportFooter的BeforePrint事件中给对应标签赋值:
if (productTotals.ContainsKey("CARGO 0.58")) { xrLabel61.Text = productTotals["CARGO 0.58"].ToString("N2"); } if (productTotals.ContainsKey("CARGO 0.53")) { // 给对应标签赋值 }
- 在报表类中定义字典变量存储各产品的总和:
- 方式2:使用报表的计算字段
创建多个计算字段,每个字段对应一个产品的汇总,表达式使用Iif([ProductoNombre]='CARGO 0.58', [PrecioTotal], 0),然后设置该计算字段的Summary为Sum,Running为Report。
替代方案:修复手动累加代码
如果坚持用手动累加,修改如下:
- 在报表类中定义全局变量存储各产品总和:
private double cargo058Total = 0; private double cargo053Total = 0; - 在DetailBand的BeforePrint事件中累加:
string productName = GetCurrentColumnValue("ProductoNombre")?.ToString(); if (string.IsNullOrEmpty(productName)) return; double priceTotal = Convert.ToDouble(GetCurrentColumnValue("PrecioTotal")); switch (productName) { case "CARGO 0.58": cargo058Total += priceTotal; break; case "CARGO 0.53": cargo053Total += priceTotal; break; } - 在ReportFooter的BeforePrint事件中赋值:
xrLabel61.Text = cargo058Total.ToString("N2"); // 其他产品标签同理赋值
内容的提问来源于stack exchange,提问作者Luis Moises Rojas
相关产品推荐
相关产品推荐

