用 Delphi 實現報表的橫向分組列印

2021-04-17 07:12:25 字數 4302 閱讀 4751

delphi 內建的 quickreport 報表系統為我們快速製作報表提供了有力的支援。對於一些簡單的報表,包括縱向分組多表頭報表,我們幾乎不用寫一句**,就可以方便地完成報表的製作。但是對於圖一所示的橫向分組的報表,我們還需要寫一些**來控制報表的列印格式。本文就以圖一所示報表為例,向大家介紹橫向分組報表的製作方法和技巧。

首先新增乙個報表窗體 qrform1,在該窗體上新增報表控制項 quickrep1,設定其 bands 屬性,使包含標題、表頭、表細節、表腳等屬性。再在報表窗體上新增 adoconnection1 連線控制項和兩個 adodataset 控制項,分別命名為 adodatasetshqk 和 adodataset1。其中 adoconnection1 與資料庫連線,adodatasetshqk 與將要顯示和列印的資料表繫結,該資料集必須新增永久性字段。

然後用 qrshape 勾畫報表的表頭和細節。其中橫線的 shape 屬性設為 qrshorline,height=1;豎線的 shape 屬性設為 qrsvertline,width=1,豎線分割各欄位,產生縱向**線。這裡的關鍵問題是:怎樣產生報表記錄的橫向分組?為了達到**控制的目的,我們在勾畫報表細節時,在「序號」「道路名稱」上方放置橫向 qrshape100,在「損壞情況」「損壞時間」「面積」上方放置橫向 qrshape200,在整個 detailband 下方放置橫向 qrshape300。在 detailband 中的「序號」「道路名稱」位置放置 qrlabel,分別命名為 qrlabelxh 和 qrlabeldlmc,在「損壞情況」「損壞時間」「面積」位置放置 qrdbtext,分別與對應的字段對應。

實現橫向分組的原理是:在報表 detailband 的 beforeprint 事件中進行判斷,如果記錄的「序號」「道路名稱」與前一條記錄相同,就不列印 qrshape100(使其 width=0),否則列印。如果報表列印到本頁末或列印完所有記錄,就列印 qrshape300,否則 qrshape300 的寬度為 0,即不列印。

設計階段有關控制項的屬性設定為:quickrep1.dataset=adodatasetrptshqk,adodatasetshqk 和 adodataset1 的 connection=adoconnection1,adodatasetshqk 的 commandtext 屬性需要填寫 sql 語句 select … from …;adodataset1 的 active 屬性為 false。

最後在主窗體上新增** qrform1.quickrep1.preview; 和 qrform1.quickrep1.print; 預覽或直接列印報表。

unit report1;

inte***ce

uses ……

type ……

varqrform1: tqrform1;

oldstr: string;

linesperpage: integer;      //每頁已經列印的記錄數

lineperitem: integer;       //每個橫向分組的記錄數累計

linestotal: integer;        //已經列印的記錄總數

linedisplayitem: integer;   //該行顯示橫向分組公共資訊

adodataset1count: integer;  //每個橫向分組的記錄數

id: integer;                //橫向分組序號

implementation

//自定義函式:判斷是否列印到本頁頁腳

function tqrform1.ispagefoot(): boolean;

begin

result :=false;

linesperpage :=linesperpage + 1;

if quickrep1.pagenumber = 1 then

begin

if linesperpage =33 then result :=true;

endelse

begin

if linesperpage =36 then result :=true;

end;

end;

//自定義函式:判斷是否列印完所有記錄

function tqrform1.islastrecord(): boolean;

begin

adodatasetrptshqk.next;

if adodatasetrptshqk.eof then

result :=true

else

begin

adodatasetrptshqk.prior;

result :=false;

end;

end;

//初始化變數:

procedure tqrform1.quickrep1beforeprint(sender: tcustomquickrep;

var printreport: boolean);

begin

oldstr :='';

linesperpage :=0;

lineperitem :=0;

linestotal :=0;

linedisplayitem :=0;

id :=0;

adodataset1count :=0;

end;

///寫報表的細節-根據條件進行橫向分組控制:

procedure tqrform1.detailband1beforeprint(sender:tqrcustomband;

var printband:boolean);

varnewstr: string;

begin

linestotal :=linestotal + 1;

newstr :=trim(adodatasetrptshqk.fieldbyname('dlmc').asstring);

if newstr=oldstr then

qrshape100.width :=0

else

begin

adodataset1.commandtext :='select count(dlmc) as count1 from rpt_shqk where dlmc='+''''+newstr+'''';

adodataset1.active :=true;

adodataset1count :=adodataset1.fieldbyname('count1').asinteger;

adodataset1.active :=false;

lineperitem :=lineperitem + adodataset1count;

linedisplayitem :=lineperitem - adodataset1count div 2;

qrshape100.width :=285;

oldstr :=trim(newstr);

id :=id + 1;

end;

if linestotal = linedisplayitem then

begin

qrlabelxh.caption :=inttostr(id);

qrlabeldlmc.caption :=trim(adodatasetrptshqk.fieldbyname('dlmc').asstring);

endelse

begin

qrlabelxh.caption :='';

qrlabeldlmc.caption :='';

end;

//根據條件畫底線:

qrshape300.width :=0;

//1,如果一頁輸出完畢,畫底線:

if ispagefoot() then

begin

qrshape300.width :=697;

linesperpage :=0;

end;

//2,如果記錄輸出完畢,畫底線:

if islastrecord() then qrshape300.width :=697;

end;

procedure tqrform1.formclosequery(sender: tobject;var canclose: boolean);

begin

quickrep1.free;

end;

procedure tqrform1.quickrep1startpage(sender: tcustomquickrep);

begin

adodatasetrptshqk.active :=true;

end;

end.

張慶 email: [email protected]

用Visual C 輕鬆實現報表處理

資料庫在企業軟體系統中應用廣泛,而報表的顯示與列印成為此類軟體必備的功能 前言資料庫在企業軟體系統中應用廣泛,而報表的顯示與列印成為此類軟體必備的功能。可惜vc 並沒有整合報表處理工具,但其強大的功能再加上市面上功能完備的報表處理工具使這一工作變得容易,本文介紹了在vc 環境中利用seagate公司...

潤幹報表 資料橫向擴充套件列太多時實現換行

潤幹報表,橫向擴充套件,資料很多時,會有很多的列,因此瀏覽效果可能不好。因此,我想橫向擴充套件的時候,到達一定資料自動換行,實現下圖效果 資料集 ds1 select name,price,rownum from foods 潤幹 a1 ds1.count 用於計算此資料集內的資料個數。b1 int...

可橫向或部分橫向滑動的列表實現

先看下效果 首先需要構造乙個header部分,header部分分為固定header和滑動header,滑動header採用橫向scrollview實現 private void bindheader rightheader new linearlayout context for string st...