彩票走势图

使用ActiveReports for .net 进行报表开发(五)—交叉报表

转帖|其它|编辑:郝浩|2011-10-28 14:50:24.000|阅读 483 次

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

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

  交叉报表是一种常见的报表类型,而且开发起来也是比较烦琐的一种报表,在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写在代码中,调试成问题,如果写成存储过程,有破坏了封装。所以相比之下,在代码中进行的转换工作虽然较复杂,但是还是具有灵活的优势的。


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn

文章转载自:博客园

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP