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

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

  關鍵詞: 動態交叉表;水晶報表;Push模式;動態綁定

0 引言

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

  水晶報表是一款商務智能軟件,主要用于設計產生報表,是業內功能最強的報表系統[2],其出現的目的就是使計算機參與到辦公系統業務流程中。

1 問題的提出

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

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

2 生成動態交叉表

  首先在數據庫服務器端完成列項名稱與個數固定的動態交叉表的生成。設每學期最多有8門課,實現方法如下:

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

003.jpg

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

  as return

  (

  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

  )

  (2)創建存儲過程upCreateJCB,功能是按學號對應,把順序編號為1的4號課程成績放在Cj1列中,把順序編號為2的5號課程成績放在Cj2列中,以此類推,最后計算每個學生的總評分。運行結果如圖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

  (

  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

  )

  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 水晶報表動態綁定數據源

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

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

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

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

  經過上述過程設計的報表MyCry.rpt如圖6所示。

005.jpg

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

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

  using CrystalDecisions.Shared;

  using CrystalDecisions.CrystalReports.Engine;

  //Load事件下執行的代碼

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

  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);

  //向水晶報表中傳參數

  ParameterFields_ps=new ParameterFields();

  //TermNo參數

  ParameterField_p=new ParameterField();

  ParameterDiscreteValue_v=new ParameterDiscreteValue();

  _p.ParameterFieldName="TermNo";

  _v.Value=xq;

  _p.CurrentValues.Add(_v);

  _ps.Add(_p);

  //ClassName參數

  _p=new ParameterField();

  _v=new ParameterDiscreteValue();

  _p.ParameterFieldName="ClassName";

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

  _p.CurrentValues.Add(_v);

  _ps.Add(_p);

  //n個課程名稱參數

  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列時后面內容填空

  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 結論

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

參考文獻

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

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

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


此內容為AET網站原創,未經授權禁止轉載。
主站蜘蛛池模板: 小镇姑娘hd电影在线观看| 欧美换爱交换乱理伦片不卡片| 国产精品免费无遮挡无码永久视频| 中文字幕中文字幕在线| 欧美videos欧美同志| 全部免费a级毛片| 麻豆国产在线不卡一区二区| 在线免费观看你懂的| 中文字幕在线免费观看视频| 欧美一区二区久久精品| 伊人大杳焦在线| 色多网站免费视频| 国产精品20p| igao视频网站| 无码人妻精品一区二区三18禁 | 免费的三级毛片| 高清色黄毛片一级毛片| 国产线路中文字幕| 一二三四在线观看免费中文动漫版 | 成年人在线播放| 亚洲AV无码久久久久网站蜜桃| 国产成人精品999在线观看| 扒开双腿猛进入免费视频黄| 国产亚洲欧美日韩精品一区二区| 2021麻豆剧果冻传媒影视| 好看的中文字幕在线| 久久久久久AV无码免费网站| 最近高清中文在线国语字幕| 亚洲精品无码久久久久秋霞| 精品国产a∨无码一区二区三区| 国产免费小视频| japonensisjava野外vt| 在线观看免费国产视频| 一级成人a毛片免费播放| 日本按摩高潮a级中文片| 亚洲五月丁香综合视频| 永久看日本大片免费35分钟| 动漫美女羞羞网站| 艺校水嫩漂亮得2美女| 国产成人福利在线视频播放尤物| 3d动漫精品啪啪一区二区中文|