程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 使用ActiveReports for .net 進行報表開發-交叉報表

使用ActiveReports for .net 進行報表開發-交叉報表

編輯:.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寫在代碼中,調試成問題,如果寫成存儲過程,有破壞了封裝。所以相比之下,在代碼中進行的轉換工作雖然較復雜,但是還是具有靈活的優勢的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved