使用ActiveReports for .net 进行报表开发-交叉报表

 

交叉报表是一种常见的报表类型,而且开发起来也是比较烦琐的一种报表,在ActiveReport中,对交叉报表提供了足够的灵活性,使你能够应对各种复杂的业务逻辑。在上篇随笔演示了显示主从表后,本篇随笔简单介绍如何制作交叉报表。

交叉报表的一个常见应用就是用作显示销售额的报表上,例如,显示多个连锁店一年内每个月的销售额,常把月份作为列来显示,每个店用一行来表示:

店名     1      2          3        4     ……………   

AC       500       200         10000       50000    ……………

BC       511       85245        4545      124578    ……………

但是在数据库中的存储常常采用下面的方式

Sales         Month         Shop

12312           1            AB

243423          2            AB

323232          3            AB

1231312         1            BC

1232            2            BC

这样就需要在显示前对数据进行处理,把销售额和月份转换到列上,我们可以在取数据时使用sql来进行这些操作,在这里,为了演示在activeReport中的使用,把转换放到报表里来作,为了简化例子,我们只显示第一个季度每月的销售额。

1.       取数据:

使用Select Sales,Month,Shop from CrossReport Order by Shop这样的sql直接取数据,不作任何合计或转换处理。

2.       转换:

我们来定义一个简单的对象来表示最终要显示的记录:

public class Sale

{

    public decimal  money1; //一月

    public decimal money2; //二月

    public decimal money3; //三月

    public string shopname;

}

同时在定义一个Sale的集合sales,来保存转换后的数据。

由于在表中每个店会对应多条记录,为了把多条记录合并为一条,要进行下面的转换动作:

//用来保存已经计算过的店铺,保证每个店铺只有一条记录

ArrayList shopname = new ArrayList();

while (dr.Read())

{

        if (!shopname.Contains(dr.GetString(2))) //该店铺的第一条记录

        {

                Sale s = new Sale ();

        s.shopname = dr.GetString(2); //取店名  shopname.Add(s.shopname);

                if (dr.GetInt32(1) == 1) //一月

                {

                        s.money1 = dr.GetDecimal(0);

}

                else if (dr.GetInt32(1) == 2) //二月

                {

                        s.money2 = dr.GetDecimal(0);

                }

                else if (dr.GetInt32(1) == 3) //三月

                {

                        s.money3 = dr.GetDecimal(0);

                }

                sales.Add(s);

        }

        else //不是该店铺的第一条记录

        {

                Sale s = ( Sale )sale [sales.Count - 1];

                if (dr.GetInt32(1) == 1)

                {

                        s.money1 = dr.GetDecimal(0);

}

                else if (dr.GetInt32(1) == 2)

                {

                        s.money2 = dr.GetDecimal(0);

                }

                else if (dr.GetInt32(1) == 3)

                {

                        s.money3 = dr.GetDecimal(0);

                }

        }

}

3.       表示:

上面是对从数据库中取出的记录作转换,将其变成在报表上要显示的格式。接下来就要在报表上显示Sales集合中的数据了。我们可以按照前几篇随笔中介绍的方法来作:

         在界面上摆放控件,并设置其FiledName字段

         在报表的DataInitialize事件中设置Filed集合,取出数据:

this.Fields.Add("money1");

        this.Fields.Add("money2");

        this.Fields.Add("money3");

        this.Fields.Add("shopname");

this.GetReportData();  //取数据并作转换

         设置一个标记来表示是否显示到了最后一条记录:

int index = 0;

         FetchData事件中显示Sales集合中的数据:

if (index == sales.Count ) //如果到了最后一条记录,就跳出

        {

                eArgs.EOF = true;

                return;

        }

        else

        {

                eArgs.EOF = false;

        }

        Sale s = ( Sale )sales[index];

        this.Fields["shopname"].Value = s.shopname;

        this.Fields["money1"].Value = s.money1;

        this.Fields["money2"].Value = s.money2;

        this.Fields["money3"].Value = s.money3;

index+=1;

按照上面的步骤,主要的代码都完成了,当然要在窗体上显示,还要加一个Viewer,然后指定加载的报表:

ActiveReports1 rpt = new ActiveReports1();

rpt.Run();

this.viewer1.Document = rpt.Document;

如果你不满意显示的效果,可以给报表加上线框,让其显示成表格。

总结:

例子中的代码有重复,但是为了说明转换的过程,没有作优化,另外,也可以看到,代码中使用了ArrayList,出现了装箱,拆箱的动作,所以性能还有优化的空间。

从表数据到显示用数据的转换可以在Sql中作,但是业务逻辑较复杂的时候,Sql就显得力不从心,例如,显示每月的数据,而且还有收入,支出,如果再加上税收,折扣,损耗,租金,和上年同期的比较等等无法预测的业务逻辑,如果把SQL写在代码中,调试成问题,如果写成存储过程,有破坏了封装。所以相比之下,在代码中进行的转换工作虽然较复杂,但是还是具有灵活的优势的。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
补丁下载(1.15M): http://u.115.com/file/f8f8e7d9fa# Ver2.45.407 重大功能完善: 1.当计算公式出错导致生成报表失败,退出调用AC Report的程序时发生内存错误。 2.含有子报表且子报表的列数大于主报表,不能导出到Excel的问题。 3.和Skin皮肤控件冲突的问题(主要是导出Excel后报错)。 4.进一步完善导出Excel的算法,将多个页面格式迥异的报表导出在一个Sheet上时,改进了算法,使得在Excel中所需列的数量和宽度计算精确度更高,真正做到无失真导出,容错性更好,对于任何复杂的报表,都可以正确导出 Ver2.45主要变动 1.修正了独立子报表(未嵌入到所属页面的子报表)预览后退出程序时,发生内存泄漏的bug。 2.图片单元格支持在公式中设置URL链接地址。 3.Cell()函数空值处理。 4.界面修改。 5.修正VCL控件和demo编译出错的问题 ACReport简介 Anycell Report(简称AC Report)是一款中国式报表组件,是国内最早的基于表格,支持图文混排、公式和脚本的中国式报表工具之一。就如Anycell Report的名称那样,灵活强大的表格功能一直是AC Report区别于其它软件或控件最显著的特征之一,AC Report 表格取消了传统表格概念中“列”的概念,每一行上的单元格数量可以不等,且可以自由活动,勿须上下对齐,在制作复杂的中国式报表时可以避免很多不必要的合并拆分操作,制作表格更加方便和随心所欲,并且省时省力。AC Report单元格支持多种丰富的形态,例如格式化文本、图片、图表、条码、OLE容器等。 AC Report的一些基本特点: 1.独具特色的表格,风格与Word表格相似,但可以做出比Word或Excel更灵活的表格来。 2. 功能全面、专业的中国式报表设计器,中国用户更易于学习和接受。 3.支持多种单元格样式,可以打印图像、图表(直方图、折线图等)、Rich文本、 条形码、中式财务帐薄、支持在报表中嵌入Word、Excel文档等。 4. 强大的计算和合计功能。内置表达式解析系统和函数库。 5. 可扩充性,可以在应用程序中给报表引擎扩充函数库、报表样式和单元格样式。 6.支持多种报表样式,如清单式、分组、交叉表、以及子报表等。 7. 支持多栏式报表。 8. 和应用程序完美结合,支持windows下所有的开发工具和程序语言(例如Delphi、C++、VB、PB、.NET、易语言),最终用户在设计器里可直接选择打印字段,生成表达式,报表设计器用户容易学习理解。 9. 支持脚本和窗体编程,报表设计人员可以编写脚本、在报表设计器里为报表添加窗体,为最终用户提供更丰富的交互功能。 10. 既可以使用应用程序中的数据集,也支持在报表中直接连接各种数据库,通过SQL直接获得报表需要的数据。 11.无失真导出为Excel、Word、Html格式的文档

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值