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

來源:互聯網
上載者:User

【IT168 技術文檔】

    交叉報表是一種常見的報表類型,而且開發起來也是比較煩瑣的一種報表,在ActiveReport中,對交叉報表提供了足夠的靈活性,使你能夠應對各種複雜的商務邏輯。在上篇隨筆示範了顯示主從表後,本篇隨筆簡單介紹如何製作交叉報表。

    交叉報表的一個常見應用就是用作顯示銷售額的報表上,例如,顯示多個連鎖店一年內每個月的銷售額,常把月份作為列來顯示,每個店用一行來表示:

店名 1月 2月 3月 ……………
AC 500 200 10000 ……………
BC 511 85245 4545 ……………

    但是在資料庫中的儲存常常採用下面的方式

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.