轉(zhuǎn)帖|其它|編輯:郝浩|2011-10-28 14:50:24.000|閱讀 483 次
概述:交叉報表是一種常見的報表類型,而且開發(fā)起來也是比較煩瑣的一種報表,在ActiveReport中,對交叉報表提供了足夠的靈活性,使你能夠應(yīng)對各種復(fù)雜的業(yè)務(wù)邏輯。在上篇隨筆演示了顯示主從表后,本篇隨筆簡單介紹如何制作交叉報表。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
交叉報表是一種常見的報表類型,而且開發(fā)起來也是比較煩瑣的一種報表,在ActiveReport中,對交叉報表提供了足夠的靈活性,使你能夠應(yīng)對各種復(fù)雜的業(yè)務(wù)邏輯。在上篇隨筆演示了顯示主從表后,本篇隨筆簡單介紹如何制作交叉報表。
交叉報表的一個常見應(yīng)用就是用作顯示銷售額的報表上,例如,顯示多個連鎖店一年內(nèi)每個月的銷售額,常把月份作為列來顯示,每個店用一行來表示:
店名 1月 2月 3月 4月 ……………
AC 500 200 10000 50000 ……………
BC 511 85245 4545 124578 ……………
但是在數(shù)據(jù)庫中的存儲常常采用下面的方式
Sales Month Shop
12312 1 AB
243423 2 AB
323232 3 AB
1231312 1 BC
1232 2 BC
這樣就需要在顯示前對數(shù)據(jù)進(jìn)行處理,把銷售額和月份轉(zhuǎn)換到列上,我們可以在取數(shù)據(jù)時使用sql來進(jìn)行這些操作,在這里,為了演示在activeReport中的使用,把轉(zhuǎn)換放到報表里來作,為了簡化例子,我們只顯示第一個季度每月的銷售額。
1、取數(shù)據(jù):
使用Select Sales,Month,Shop from CrossReport Order by Shop這樣的sql直接取數(shù)據(jù),不作任何合計或轉(zhuǎn)換處理。
2、 轉(zhuǎn)換:
我們來定義一個簡單的對象來表示最終要顯示的記錄:
public class Sale
{
public decimal money1; //一月
public decimal money2; //二月
public decimal money3; //三月
public string shopname;
}
同時在定義一個Sale的集合sales,來保存轉(zhuǎn)換后的數(shù)據(jù)。
由于在表中每個店會對應(yīng)多條記錄,為了把多條記錄合并為一條,要進(jìn)行下面的轉(zhuǎn)換動作:
//用來保存已經(jīng)計算過的店鋪,保證每個店鋪只有一條記錄
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、表示:
上面是對從數(shù)據(jù)庫中取出的記錄作轉(zhuǎn)換,將其變成在報表上要顯示的格式。接下來就要在報表上顯示Sales集合中的數(shù)據(jù)了。我們可以按照前幾篇隨筆中介紹的方法來作:
? 在界面上擺放控件,并設(shè)置其FiledName字段
? 在報表的DataInitialize事件中設(shè)置Filed集合,取出數(shù)據(jù):
this.Fields.Add("money1");
this.Fields.Add("money2");
this.Fields.Add("money3");
this.Fields.Add("shopname");
this.GetReportData(); //取數(shù)據(jù)并作轉(zhuǎn)換
? 設(shè)置一個標(biāo)記來表示是否顯示到了最后一條記錄:
int index = 0;
? 在FetchData事件中顯示Sales集合中的數(shù)據(jù):
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;
按照上面的步驟,主要的代碼都完成了,當(dāng)然要在窗體上顯示,還要加一個Viewer,然后指定加載的報表:
ActiveReports1 rpt = new ActiveReports1();
rpt.Run();
this.viewer1.Document = rpt.Document;
如果你不滿意顯示的效果,可以給報表加上線框,讓其顯示成表格。
總結(jié):
例子中的代碼有重復(fù),但是為了說明轉(zhuǎn)換的過程,沒有作優(yōu)化,另外,也可以看到,代碼中使用了ArrayList,出現(xiàn)了裝箱,拆箱的動作,所以性能還有優(yōu)化的空間。
從表數(shù)據(jù)到顯示用數(shù)據(jù)的轉(zhuǎn)換可以在Sql中作,但是業(yè)務(wù)邏輯較復(fù)雜的時候,Sql就顯得力不從心,例如,顯示每月的數(shù)據(jù),而且還有收入,支出,如果再加上稅收,折扣,損耗,租金,和上年同期的比較等等無法預(yù)測的業(yè)務(wù)邏輯,如果把SQL寫在代碼中,調(diào)試成問題,如果寫成存儲過程,有破壞了封裝。所以相比之下,在代碼中進(jìn)行的轉(zhuǎn)換工作雖然較復(fù)雜,但是還是具有靈活的優(yōu)勢的。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:博客園