《電子技術應用》
您所在的位置:首頁 > 嵌入式技術 > 設計應用 > 利用水晶報表動態綁定數據源實現動態交叉表的方法研究
利用水晶報表動態綁定數據源實現動態交叉表的方法研究
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網站原創,未經授權禁止轉載。
亚洲一区二区欧美_亚洲丝袜一区_99re亚洲国产精品_日韩亚洲一区二区
精品99一区二区三区| 亚洲欧美日韩国产成人| 欧美日韩一级大片网址| 麻豆freexxxx性91精品| 久久精品一区四区| 亚洲欧美日韩综合| 亚洲一区二区三区成人在线视频精品| 亚洲精品国产精品国自产在线| 午夜亚洲福利| 亚洲一区二区三区高清不卡| 中文av一区二区| 一区二区三区蜜桃网| av成人免费| 99视频日韩| 正在播放欧美视频| 夜夜夜精品看看| 99亚洲伊人久久精品影院红桃| 日韩一级成人av| 日韩一级黄色大片| 中日韩视频在线观看| 亚洲午夜久久久久久久久电影院| 亚洲素人一区二区| 亚洲自拍偷拍福利| 亚洲欧美在线网| 欧美在线一级视频| 久久精品亚洲一区二区三区浴池 | 亚洲欧美日韩另类| 午夜精品免费在线| 欧美资源在线| 亚洲国产专区| 日韩网站在线看片你懂的| 一本一本久久a久久精品综合妖精 一本一本久久a久久精品综合麻豆 | 91久久精品国产| 99精品热视频| 亚洲欧美综合国产精品一区| 欧美在线综合| 免费观看久久久4p| 欧美日韩亚洲综合在线| 国产模特精品视频久久久久| 国内精品亚洲| 亚洲激情专区| 亚洲午夜精品17c| 久久国产精品久久国产精品| 亚洲成人自拍视频| 一区二区三区精品视频在线观看| 亚洲自拍偷拍视频| 久久久天天操| 欧美高清不卡在线| 国产精品观看| 一区在线视频| 亚洲视频一区在线观看| 羞羞答答国产精品www一本| 亚洲日产国产精品| 亚洲欧美中文日韩v在线观看| 久久久噜噜噜久久久| 欧美啪啪一区| 国产婷婷色综合av蜜臀av| 亚洲激情视频在线播放| 亚洲综合日韩在线| 亚洲精品在线视频| 先锋影音国产一区| 欧美激情一区二区三区在线| 国产精品视频xxx| 亚洲高清一区二| 亚洲免费综合| 999在线观看精品免费不卡网站| 欧美一区2区视频在线观看| 另类国产ts人妖高潮视频| 欧美午夜剧场| 在线看日韩av| 亚洲欧美日本国产有色| 亚洲美女视频| 久久深夜福利免费观看| 欧美性生交xxxxx久久久| 精品成人国产| 亚洲男人的天堂在线aⅴ视频| 日韩一区二区精品视频| 久久色在线播放| 国产精品亚洲第一区在线暖暖韩国| 亚洲国产三级在线| 久久成人免费日本黄色| 亚洲一区二区三区中文字幕| 免费观看在线综合| 国产一区二区三区在线观看视频 | 一本色道久久综合一区| 亚洲大黄网站| 性欧美大战久久久久久久免费观看| 欧美国产日产韩国视频| 国产一区二区三区四区在线观看 | 亚洲欧美日韩精品在线| 亚洲天堂成人在线视频| 毛片基地黄久久久久久天堂| 国产精品你懂的在线| 亚洲精品在线二区| 亚洲国产精品高清久久久| 欧美一区2区视频在线观看| 欧美网站在线观看| 亚洲国产天堂久久综合| 久久国产精品一区二区三区| 欧美亚洲专区| 国产精品久久久久一区二区三区共| 91久久久一线二线三线品牌| 久久精品国产一区二区电影| 先锋资源久久| 国产精品美女久久| 一区二区三区四区蜜桃| 一区二区毛片| 欧美日韩第一页| 亚洲人精品午夜| 日韩午夜三级在线| 免费成人av资源网| 一区国产精品| 久久精品免费看| 久久久久久久久综合| 国产一区二区欧美日韩| 午夜精品99久久免费| 亚洲一区999| 欧美偷拍一区二区| 国产精品99久久久久久白浆小说| 亚洲一区二三| 国产精品乱码妇女bbbb| 亚洲视屏在线播放| 香蕉久久国产| 国产亚洲免费的视频看| 欧美一区二区三区视频在线观看| 久久国内精品自在自线400部| 国产欧美一区二区三区在线老狼 | 亚洲视频日本| 欧美日韩中字| 亚洲图片欧美午夜| 亚洲欧美在线免费观看| 国产精品免费小视频| 亚洲欧美春色| 久久久久久久久伊人| 在线观看日韩av| 亚洲精品影院在线观看| 欧美日韩第一区日日骚| 中文久久精品| 性色av一区二区三区| 国产一区二区三区四区老人| 亚洲高清视频在线观看| 欧美精品久久久久久久久久| 一本色道久久| 午夜欧美大片免费观看| 国产一区二区日韩精品欧美精品| 亚洲福利国产| 欧美激情一区二区三区不卡| 在线亚洲观看| 久久九九国产| 亚洲国产精品电影在线观看| 99视频有精品| 国产精品综合色区在线观看| 欧美一区=区| 欧美成人有码| 一区二区三区四区国产| 久久精品欧美| 亚洲激情在线观看| 亚洲综合色婷婷| 国产在线视频不卡二| 亚洲免费av片| 国产精品一区二区三区久久| 亚洲高清视频一区| 欧美日韩在线另类| 欧美有码在线观看视频| 欧美乱妇高清无乱码| 亚洲欧美欧美一区二区三区| 免费在线亚洲| 在线视频你懂得一区| 久久久精品国产一区二区三区| 亚洲国产成人一区| 亚洲欧美日本另类| 在线国产日韩| 午夜精品福利在线观看| 亚洲缚视频在线观看| 亚洲在线不卡| 樱桃成人精品视频在线播放| 亚洲一区二区不卡免费| 韩国精品一区二区三区| 亚洲深夜福利视频| 国产一区亚洲一区| 一道本一区二区| 国模一区二区三区| 亚洲午夜女主播在线直播| 韩日午夜在线资源一区二区| 亚洲午夜激情免费视频| 一区二区亚洲欧洲国产日韩| 亚洲欧美综合v| 亚洲精品乱码久久久久久蜜桃麻豆| 先锋资源久久| 亚洲蜜桃精久久久久久久| 久久久久一区二区三区| 中文亚洲字幕| 欧美jizzhd精品欧美喷水 | 日韩网站免费观看| 国产自产v一区二区三区c| 亚洲一区免费观看| 亚洲国产成人av在线| 久久激情中文| 夜夜夜久久久| 欧美精品精品一区|