《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技術(shù) > 設(shè)計應(yīng)用 > 利用水晶報表動態(tài)綁定數(shù)據(jù)源實現(xiàn)動態(tài)交叉表的方法研究
利用水晶報表動態(tài)綁定數(shù)據(jù)源實現(xiàn)動態(tài)交叉表的方法研究
2015年微型機與應(yīng)用第10期
劉 輝1,常婉綸1,劉豫凡2
(1.西安理工大學(xué),陜西 西安 710082; 2.西北工業(yè)大學(xué) 機電學(xué)院 陜西 西安 710072)
摘要: 為減少數(shù)據(jù)冗余,根據(jù)規(guī)范化理論設(shè)計的數(shù)據(jù)庫不能直接輸出分類匯總的結(jié)果,需要進行轉(zhuǎn)換生成交叉表,并利用水晶報表的Push模式實現(xiàn)對交叉表的顯示。在.NET和SQL Server環(huán)境下,探討了動態(tài)交叉表的生成和利用水晶報表動態(tài)綁定數(shù)據(jù)源顯示數(shù)據(jù)的方法,并給出了較為詳細的實現(xiàn)過程。
Abstract:
Key words :

  摘  要: 為減少數(shù)據(jù)冗余,根據(jù)規(guī)范化理論設(shè)計的數(shù)據(jù)庫不能直接輸出分類匯總的結(jié)果,需要進行轉(zhuǎn)換生成交叉表,并利用水晶報表Push模式實現(xiàn)對交叉表的顯示。在.NET和SQL Server環(huán)境下,探討了動態(tài)交叉表的生成和利用水晶報表動態(tài)綁定數(shù)據(jù)源顯示數(shù)據(jù)的方法,并給出了較為詳細的實現(xiàn)過程。

  關(guān)鍵詞: 動態(tài)交叉表;水晶報表;Push模式;動態(tài)綁定

0 引言

  信息系統(tǒng)中都不能缺少報表,而交叉表是種常見的報表形式,它將源表中的數(shù)據(jù)分組匯總后,一組列在表的左側(cè),另一組列在表的上部,從而形成一種分類匯總表格[1]。動態(tài)交叉表是按用戶呈現(xiàn)數(shù)據(jù)的要求,不僅對數(shù)據(jù)進行分類,同時還要根據(jù)表中數(shù)據(jù)的情況動態(tài)創(chuàng)建列,把數(shù)據(jù)行信息置換到表格列處并進行匯總。

  水晶報表是一款商務(wù)智能軟件,主要用于設(shè)計產(chǎn)生報表,是業(yè)內(nèi)功能最強的報表系統(tǒng)[2],其出現(xiàn)的目的就是使計算機參與到辦公系統(tǒng)業(yè)務(wù)流程中。

1 問題的提出

  以我校學(xué)生成績管理系統(tǒng)為例,為消除存儲異常,減少數(shù)據(jù)冗余,保證數(shù)據(jù)的完整性,按規(guī)范化設(shè)計理論設(shè)計的數(shù)據(jù)庫含多張表,其中與成績有關(guān)的3個表的關(guān)系模式學(xué)生信息表S(學(xué)號、姓名、性別、班號)、課程信息表C(課號、課名)、學(xué)生成績表SC(學(xué)號、課號、學(xué)期、成績)之間的關(guān)系圖如圖1所示。學(xué)生成績表中的數(shù)據(jù)形式如圖2所示。實際工作中需要打印的學(xué)生成績表如圖3所示。

  由此可見,數(shù)據(jù)庫中存儲的數(shù)據(jù),在某些應(yīng)用中,需要生成動態(tài)交叉表,因不同班級不同學(xué)期學(xué)生學(xué)習(xí)的課程不一樣,生成的動態(tài)交叉表的列項的個數(shù)和名稱都是不固定的。經(jīng)驗表明,水晶報表雖然功能強大且使用方便,但它要求設(shè)計表格時所使用的表名以及列名與使用時必須一致。本文研究了水晶報表的Pull模式和Push模式[3],提出了在數(shù)據(jù)庫端生成一個表格列項固定的動態(tài)交叉表,利用Push模式動態(tài)綁定數(shù)據(jù)源把數(shù)據(jù)推送給水晶報表引擎的方法。

2 生成動態(tài)交叉表

  首先在數(shù)據(jù)庫服務(wù)器端完成列項名稱與個數(shù)固定的動態(tài)交叉表的生成。設(shè)每學(xué)期最多有8門課,實現(xiàn)方法如下:

  (1)創(chuàng)建函數(shù)ufGetCourse,功能是篩選出某班對應(yīng)學(xué)期的課程,并按順序編號。運行結(jié)果如圖4所示。

003.jpg

  create function ufGetCourse(@bno int,@tnum int)returns table

  as return

 ?。?/p>

  select col=count(*),tc1.cno,cname

  from(select distinct cno from s join sc on s.sno=sc.sno where bno=@bno and tnum=@tnum)as tc1

  join(select distinct cno from s join sc on s.sno=sc.sno where bno=@bno and tnum=@tnum)as tc2

  on tc1.cno>=tc2.cno

  join c on tc1.cno=c.cno

  group by tc1.cno,cname

 ?。?/p>

 ?。?)創(chuàng)建存儲過程upCreateJCB,功能是按學(xué)號對應(yīng),把順序編號為1的4號課程成績放在Cj1列中,把順序編號為2的5號課程成績放在Cj2列中,以此類推,最后計算每個學(xué)生的總評分。運行結(jié)果如圖5所示。

004.jpg

  create proc upCreateJCB

  @bno int,@tnum int

  as

  declare @str varchar(100),@cstu varchar(100),@cno int,@sno char(10),@sname varchar(50),@sc int,@col int,@ZF int

  create table #t

 ?。?/p>

  sno char(10),sname varchar(50),ZF decimal(5,1),

  cj1 int,cj2 int,cj3 int,cj4 int,cj5 int,cj6 int,cj7 int,cj8 int

 ?。?/p>

  declare my_C cursor for select s.sno,sname,col,sc.cno,Score from S join SC on s.sno=sc.sno join(select*from dbo.ufGetCourse(@bno,@tnum))as c on sc.cno=c.cno where bno=@bno and tnum=@tnum order by sno

  open my_C

  fetch next from my_C into@sno,@sname,@col,@cno,@sc

  while @@fetch_status=0

  begin

  select@cstu=@sno,@ZF=0

  insert into#t(sno,sname)values(@sno,@sname)

  while@@fetch_status=0 and@cstu=@sno

  begin

  set@str=′update#t set cj′+cast(@col as varchar(2))+′=′′′+cast(@sc as varchar(3))+′′′′

  set@str=@str+′where sno=′+@sno

  exec(@str)

  set@ZF=@ZF+@sc

  fetch next from my_C into@sno,@sname,@col,@cno,@sc

  end

  --更新總評分

  update #t set ZF=@ZF where sno=@cstu

  end

  select*from#t

  drop table#t

  close my_C

  deallocate my_C

3 水晶報表動態(tài)綁定數(shù)據(jù)源

  應(yīng)用程序的前臺界面在.NET平臺下進行水晶報表設(shè)計,采用Push模式在程序中動態(tài)加載數(shù)據(jù)源和報表,用動態(tài)傳參方式把表頭的cj1~cj8更換成對應(yīng)的中文課程名,方法如下:

  (1)建立解決方案。在解決方案資源管理器中添加“Crystal報表”模板。方法為:添加→新建項→Crystal報表→命名報表為MyCry.rpt→作為空白報表。

 ?。?)在字段資源管理器中通過“報表專家”完成報表設(shè)計。方法為:數(shù)據(jù)庫字段→數(shù)據(jù)庫專家→創(chuàng)建新鏈接→OLE DB(ADO)→Microsoft OLE DB Provider for SQL Server→填寫鏈接數(shù)據(jù)庫的信息→選擇對應(yīng)的數(shù)據(jù)庫→選擇存儲過程upCreateJCB→把涉及的字段拖拽到水晶報表細節(jié)欄中并填上表格線。

  (3)在字段資源管理器中添加參數(shù)字段:班級名classname、學(xué)期TermNo、Cj1~Cj8,并把這些參數(shù)字段拖拽到水晶報表的頁眉欄處。

  經(jīng)過上述過程設(shè)計的報表MyCry.rpt如圖6所示。

005.jpg

 ?。?)在窗體上放一個CrystalReportViewer控件并命名為crv,用C#編程動態(tài)加載數(shù)據(jù)源和報表。代碼如下:

  //程序開始處需對兩個名字空間進行引用

  using CrystalDecisions.Shared;

  using CrystalDecisions.CrystalReports.Engine;

  //Load事件下執(zhí)行的代碼

  int num,bj=197,xq=1;//197為班級號,1為第1學(xué)期

  SqlConnection con=new SqlConnection();

  con.ConnectionString="Data Source=.;Initial Catalog=Student_Score;Integrated Security=True";

  con.Open();

  string strSql="exec upCreateJCB"+bj.ToString()+","+xq.ToString();

  SqlDataAdapter da=new SqlDataAdapter(strSql,con);

  DataTable d1=new DataTable();

  da.Fill(d1);

  MyCry ocr=new MyCry();

  ocr.Load("MyCry");

  ocr.SetDataSource(d1);

  //向水晶報表中傳參數(shù)

  ParameterFields_ps=new ParameterFields();

  //TermNo參數(shù)

  ParameterField_p=new ParameterField();

  ParameterDiscreteValue_v=new ParameterDiscreteValue();

  _p.ParameterFieldName="TermNo";

  _v.Value=xq;

  _p.CurrentValues.Add(_v);

  _ps.Add(_p);

  //ClassName參數(shù)

  _p=new ParameterField();

  _v=new ParameterDiscreteValue();

  _p.ParameterFieldName="ClassName";

  _v.Value=bj;//此處可先從班級表中讀取班級名然后傳遞班級名,本例略

  _p.CurrentValues.Add(_v);

  _ps.Add(_p);

  //n個課程名稱參數(shù)

  strSql="select*from dbo.ufGetCourse("+bj.ToString()+","+xq.ToString()+")";

  SqlDataAdapter db=new SqlDataAdapter(strSql,con);

  DataTable d2=new DataTable();

  db.Fill(d2);

  for(num=1;num<=d2.Rows.Count;num++)

  {

  _p=new ParameterField();

  _v=new ParameterDiscreteValue();

  _p.ParameterFieldName="cj"+num.ToString();

  _v.Value=d2.Rows[num-1][2].ToString();

  _p.CurrentValues.Add(_v);

  _ps.Add(_p);

  }

  //報表中共有8列,不足8列時后面內(nèi)容填空

  for(;num<=8;num++)

  {

  _p=new ParameterField();

  _v=new ParameterDiscreteValue();

  _p.ParameterFieldName="cj"+num.ToString();

  _v.Value="";

  _p.CurrentValues.Add(_v);

  _ps.Add(_p);

  }

  crv.ParameterFieldInfo=_ps;

  crv.ReportSource=ocr;

4 結(jié)論

  本文提出了利用水晶報表顯示并打印動態(tài)交叉表的一種方法,圖3就是本校學(xué)籍管理系統(tǒng)中用本方法打印的成績匯總表,由于來源于真實數(shù)據(jù),故姓名處進行了處理。

參考文獻

  [1] 張賢斌,費樹岷.管理信息系統(tǒng)中動態(tài)交叉表的實現(xiàn)方式研究[J].計算機應(yīng)用工程技術(shù),2008,4(4):995-996.

  [2] 叢鳳俠,楊玉強.通用水晶報表自動生成技術(shù)研究[J].計算機技術(shù)與發(fā)展,2013,23(5):54-57.

  [3] 錢哨,李揮劍,李繼哲,等.C#WinForm實踐開發(fā)教程[M].北京:中國水利水電出版社,2010.


此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。