程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi程序執行時實時生成報表

Delphi程序執行時實時生成報表

編輯:Delphi

  當前,在軟件開發工具中,Delphi以其控件多、面向對象編程功能強、代碼執行速度快和簡單易用等特點,結合可視化開發環境和當前最快的編譯器技術,已成為全球公認的快速應用開發工具,正被愈來愈多的編程人員所采用。使用Delphi可以編寫各種Windows應用程序,尤其是開發數據庫信息管理系統有其獨特的優勢。在數據庫信息管理系統的開發的過程中,我們經常需要打印輸出很多報表,用Delphi設計復雜報表是一件比較煩鎖的事件,它沒有Visual FoxPro中那樣簡便。但由於Delphi中設計報表采用的也是控件,因此,我們可以在程序執行時直接建立所需的報表控件來實時生成報表,而且,生成的報表樣工可以由程序控制來決定。例如,我們在數據庫信息查詢時,查詢出來的結果信息結構一般是不固定的,假如我們要將查詢結果打印出來,只設計一種報表格式是不行的,為所有可能的結果信息都設計一種報表格式也不是一種很好的解決辦法。為了解決這樣一個問題,我們可以采用實時生成報表技術。本文的目的就是通過一個實例向大家詳細介紹怎樣實時生成報表。
      本例所將設計一個打印對話框,該對話框包括TQickRep控件和一些報表樣式控制控件,其它窗體外觀如下圖所示:
  1、 控件功能說明
  QuickRep:TQuickRep  它包括列標頭(HB:TQRBand)、細節(DB:TQRBand)、頁腳(FB:TQRBand)、總結(SB:TQRBand)帶區,並且細節、頁腳、總結中沒有包括一個TQRLabel、TQRExpr或TDBText控件,主要是在程序執行時建立,列標頭帶區中包括Title(TQRLabel)用於報表標題;QRSQL: TQRLabel用於查詢條件,這兩個控件的Caption屬性在程序執行時可任意更改。為了能夠讓QuickRep不顯示出來,將其置於Panel1(Tpanel)的後面,並將Panel1擴展到整個窗體;
  Query:TQuery  SQL語句控件,程序將根據Query返回的結果來生成報表。因此,在建立這個窗體時,一定要將Query.SQL屬性指定一條SQL語句;
  在以上窗體中“紙張”和“頁面設置”兩欄所包括的控件是對QuickRep.Page屬性的控制,程序執行時更改它們會直接改變QuickRep控件相應的屬性值,這可以通過OnChange或OnExit事件代碼完成;
  “打印內容設置”欄中的標題是指定報表的標題(TT:TEdit),其值與QuickRep.ReportTitle和Title.Caption一致,可以任意更改;“打印查詢條件”復選框指定是否打印查詢條件,該復選框的選取否直接控制QRSQL.Caption是否為空;“表列對齊方式”由一組選項按鈕組成,它主要用於報表生成時細節內容的對齊方式,它的更改控制變量RD1(Byte)的值(0自動對齊,1中間對齊,2左邊對齊);“表列打印寬度”由一組選項按鈕組成,主要用於在生成報表格式時列值的寬度,它的更改控制變量RD2(Byte)的值(0自動寬度,1相同寬度,2限制最大寬度),當選中1相同寬度,2限制最大寬度時要求輸入寬度,單位為像素;“統計方式”指出報表是否包含頁腳(FB:TQRBAND)和總和(SB:TQRBAND)帶區。
  2、 程序說明
  程序定義了如下類型:
        TQRLabelName=array of TQRLabel;
        TQRDBTextName=array of TQRDBText;
        TQRShapeName=array of TQRShape;
        TQRExpName=array of TQRExpr;
  上述類型為動態數組類型,數據的每個元素為一個類。在實時建立報表控件時,要建立的控件個數是不確定的且控制名稱也不能確定,用動態數組是一個比較好的解決辦法,即可以任意指定數據的維數,又不用自己管理內存分配問題,還有利於報表包含控件的釋放與處理。程序還聲明了上述類型的變量如下:
        CHBName:TQRLabelName;
        DBName:TQRDBTextName;
        CHBShape,DBShape,FBShape,SumShape:TQRShapeName;
        FBName,SumName:TQRExpName;
  這些數組變量將在窗體建立時根據Query返回的字段結果分配內存,每一個字段對就數組的一個元素。
  程序執行過程:窗體在建立並顯示時,就對本窗體建立初始化操作。在OnCreate事件中將QuickRep.Page屬性的相應值顯示出來,在OnShow事件中執行Query.Open操作,並根據返回結果分配控件數組變量空間。窗體建立後,單擊“生成”按鈕生成報表(忽略備注字段和相片字段),然後可單擊“打印”和“預覽”進行打印或者預覽報表。當產生報表後又更改了設置,必須重新生成報表。如果Query返回的結果集字段太多,生成報表時有可能紙張礦小不能將生成全部報表,可調整報表紙張大小,再生成報表。當關閉窗體時,將釋放建立的控件。
  3、 源程序清單及注釋
  unit PrintDlg;
  interface
  uses
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    StdCtrls, Buttons, ExtCtrls, Spin, QuickRpt,QRPrntr,printers, Qrctrls,
    Db, DBTables, ComCtrls,SysIni;
  type
    TQRLabelName=array of TQRLabel;//列標頭帶區中列標題控制件類動態數組
    TQRDBTextName=array of TQRDBText; //細節帶區中列標題控制件類動態數組
    TQRShapeName=array of TQRShape; //線條控制件類動態數組
    TQRExpName=array of TQRExpr; //統計控制件類動態數組
    TPrintForm = class(TForm)
      GroupBox1: TGroupBox;
      Label5: TLabel;
      BtnSet: TbitBtn;//“設置”按鈕控件
      BtnCancel: TBitBtn;// “關閉”按鈕控件
      Panel1: TPanel;
      BtnPrint: TBitBtn;// “打印”按鈕控件
      BtnPrvIEw: TBitBtn;// “預覽”按控件鈕
      QuickRep: TQuickRep;// 快速報表控件
      HB: TQRBand;// “列標頭”帶區控件
      Title: TQRLabel;// 報表標題控件
      QRE1: TQRExpr;// 列標頭帶區中“頁碼”控件
      QRE2: TQRExpr;//列標頭帶區中“日期”控件
      Panel2: TPanel;
      Label1: TLabel;
      R1: TRadioButton;//“ 縱向打印”控件
      R2: TRadioButton;// “橫向打印”控件
      GroupBox4: TGroupBox;
      TT: TEdit;// 標題輸入框控件
      Label2: TLabel;
      SR: TCheckBox;// “打印查詢條件”控件
      Label3: TLabel;
      Image1: TImage;//顯示縱向打印圖像
      Image2: TImage;//顯示橫向打印圖像
      QRSQL: TQRLabel;// 列標頭帶區中用於顯示“查詢條件”控件
      GroupBox2: TGroupBox;
      Label7: TLabel;
      Label8: TLabel;
      Label9: TLabel;
      Label10: TLabel;
      Label11: TLabel;
      Label12: TLabel;
      Label13: TLabel;
      PageSpace: TEdit;// 欄間距輸入框控件
      PageTop: TEdit;// 頁邊距上輸入框控件
      PageBottom: TEdit; // 頁邊距下輸入框控件
      PageLeft: TEdit; // 頁邊距左輸入框控件
      PageRight: TEdit; // 頁邊距右輸入框控件
      PageDlux: TCheckBox; // “雙面打印”控件
      PageCol: TEdit; // 分欄輸入框控件
      Pages: TEdit; // 打印份數輸入框控件
      PaperH: TEdit; // 紙張長度輸入框控件
      PaperW: TEdit;//紙張寬度輸入框控件
      Label4: TLabel;
      Label6: TLabel;
      Ps: TComboBox;//紙張型號列表框控件
      Query: TQuery;//SQL查詢控件
      DB: TQRBand;// “細節”帶區控件
      CrtRep: TBitBtn; // “生成”按鈕控件
      Label14: TLabel;
      Label15: TLabel;
      Panel3: TPanel;
      Wdauto: TRadioButton; // “自動寬度”控件
      Wdall: TRadioButton; // “相同寬度”控件
      Wdmax: TRadioButton; // “限制最在寬度”控件
      Label16: TLabel;
      ColWd: TEdit; // 列寬輸入框控件
      Panel4: TPanel;
      DJAUTO: TRadioButton; // “自動對齊”控件
      DJCENTER: TRadioButton; // “中間中齊”控件
      DJLEFT: TRadioButton; // “左邊對齊”控件
      FB: TQRBand; // 頁腳帶區控件
      Label17: TLabel;
      Panel5: TPanel;
      TJ1: TCheckBox; // “每頁統計”控件
      TJ2: TCheckBox; // “統計總和”控件
      SB: TQRBand; // 總和帶區控件
      procedure FormCreate(Sender: TObject);
      procedure RadioButtonClick(Sender: TObject);
      procedure PageDluxClick(Sender: TObject);
      procedure PageColChange(Sender: TObject);
      procedure PageSpaceExit(Sender: TObject);
      procedure PagesChange(Sender: TObject);
      procedure PageTopExit(Sender: TObject);
      procedure PageBottomExit(Sender: TObject);
      procedure PageLeftExit(Sender: TObject);
      procedure PageRightExit(Sender: TObject);
      procedure TTExit(Sender: TObject);
      procedure DTClick(Sender: TObject);
      procedure BtnPrvIEwClick(Sender: TObject);
      procedure BtnSetClick(Sender: TObject);
      procedure PsChange(Sender: TObject);
      procedure PaperChange(Sender: TObject);
      procedure FormClose(Sender: TObject; var Action: TCloseAction);
      procedure FormDestroy(Sender: TObject);
      procedure CreateReport(Sender: TObject);
      procedure SRClick(Sender: TObject);
      procedure ClearRep();
      procedure FormShow(Sender: TObject);
      procedure PaperSizeChg(Sender: TObject);
      procedure DJChage(Sender: TObject);
      procedure WdChage(Sender: TObject);
      procedure QuickRepStartPage(Sender: TCustomQuickRep);
      procedure BtnPrintClick(Sender: TObject);
    private
      { Private declarations }
      CHBName:TQRLabelName;//定義列標頭帶區控件名動態數組名
      DBName:TQRDBTextName; //定義細節帶區控件名動態數組名
      CHBShape,DBShape,FBShape,SumShape:TQRShapeName; //定義線條控件動態數組名
      FBName,SumName:TQRExpName; //定義頁腳(FBNAME)和總和帶區(SUMNAME)控件名動態數組名
      DJ:TAlignment;//列對齊方式(taLeftJustify, taRightJustify, taCenter)
      Rd1,Rd2:Byte;//用於保存表列對齊方式(RD1)和打印寬度(RD2)狀態變量名
    public
     { Public declarations }
  CXTJ,BT:String;//CXTJ存放查詢條件,BT存放報表標題
                 //由上一級窗體指定
    end;

  const
    PaperSize:array[0..26] of TQRPaperSize=(A3, A4, A4Small, A5, B4, B5, Letter,
                  LetterSmall, Tabloid, Ledger, Legal,Statement, Executive, Folio,
                  Quarto, qr10X14, qr11X17, Note, Env9, Env10, Env11, Env12,
                  Env14, CSheet, DSheet, ESheet, Custom);
  //QuickRep所列出的紙張類型

  var
    PrintForm: TPrintForm;

  implementation

  {$R *.DFM}

  procedure TPrintForm.FormCreate(Sender: TObject);
  //將QuickRep.Page屬性以及其它屬性值顯示出來
  var
    I:Byte;
  begin
    PageCol.Text:=IntToStr(QuickRep.Page.Columns);
    PageSpace.Text:=FormatFloat('0.00',QuickRep.Page.ColumnSpace);
    PageTop.Text:=FormatFloat('0.00',QuickRep.Page.TopMargin);
    PageBottom.Text:=FormatFloat('0.00',QuickRep.Page.BottomMargin);
    PageLeft.Text:=FormatFloat('0.00',QuickRep.Page.LeftMargin);
    PageRight.Text:=FormatFloat('0.00',QuickRep.Page.RightMargin);
    PageSpace.Text:=FormatFloat('0.00',QuickRep.page.ColumnSpace);
    R1.Checked:=QuickRep.Page.OrIEntation=poPortrait;
    Image1.Visible:=R1.Checked;
    R2.Checked:=QuickRep.Page.OrIEntation=poLandscape;
    Image2.Visible:=R2.Checked;
    PageDlux.Checked:=QuickRep.PrinterSettings.Duplex;
    Pages.Text:=IntToStr(QuickRep.PrinterSettings.CopIEs);
    PaperH.Text:=FormatFloat('0.00',QuickRep.Page.Length);
    PaperW.Text:=FormatFloat('0.00',QuickRep.Page.Width);
    For I:=0 to 26 do     //PS列表框顯示紙張類型
      if QuickRep.Page.PaperSize=PaperSize[I] then begin
         PS.ItemIndex:=I;
         Break;
  end;
  //判斷紙張寬度是否可以更改,只有紙張類型為自定義(Ps.ItemIndex=26)才能更改
    PaperH.Enabled:=Ps.ItemIndex=26;
    PaperW.Enabled:=Ps.ItemIndex=26;
  end;

  procedure TPrintForm.RadioButtonClick(Sender: TObject);
  //紙張方向改變事件處理
  var
    S:String;
  begin
    Image1.Visible:=R1.Checked;
    Image2.Visible:=R2.Checked;
    if R1.Checked then
      QuickRep.Page.OrIEntation:=poPortrait
    else
      QuickRep.Page.OrIEntation:=poLandscape;
    //交換紙張寬度和長度的值
    S:=PaperH.Text;
    PaperH.Text:=PaperW.Text;
    PaperW.Text:=S;
    if (Ps.ItemIndex=26) or (Ps.ItemIndex=0) then begin
      QuickRep.Page.Width:=StrToFloat(PaperW.Text);
      QuickRep.Page.Length:=StrToFloat(PaperH.Text);
    end;
  end;

  procedure TPrintForm.PageDluxClick(Sender: TObject);
  begin
    QuickRep.PrinterSettings.Duplex:=PageDlux.Checked;
  end;

  procedure TPrintForm.PageColChange(Sender: TObject);
  begin
    if StrToInt(PageCol.Text)<1 then PageCol.Text:='1';
    QuickRep.Page.Columns:=StrToInt(PageCol.Text);
  end;

  procedure TPrintForm.PageSpaceExit(Sender: TObject);
  begin
    QuickRep.Page.ColumnSpace:=StrToFloat(PageSpace.Text);
  end;

  procedure TPrintForm.PagesChange(Sender: TObject);
  begin
    if StrToInt(Pages.Text)<1 then Pages.Text:='1';
    QuickRep.PrinterSettings.CopIEs:=StrToInt(Pages.Text);
  end;

  procedure TPrintForm.PageTopExit(Sender: TObject);
  begin
    QuickRep.Page.TopMargin:=StrToFloat(PageTop.Text);
  end;

  procedure TPrintForm.PageBottomExit(Sender: TObject);
  begin
    QuickRep.Page.BottomMargin:=StrToFloat(PageBottom.Text);
  end;

  procedure TPrintForm.PageLeftExit(Sender: TObject);
  begin
    QuickRep.Page.LeftMargin:=StrToFloat(PageLeft.Text);
  end;

  procedure TPrintForm.PageRightExit(Sender: TObject);
  begin
    QuickRep.Page.RightMargin:=StrToFloat(PageRight.Text);
  end;

  procedure TPrintForm.TTExit(Sender: TObject);//標題更改事件處理
  begin
    QuickRep.ReportTitle:=TT.Text;
    Title.Caption:=TT.Text;
    Bt:=TT.Text;
  end;

  procedure TPrintForm.DTClick(Sender: TObject);//打印查詢條件復選框事件
  begin
    QRSQL.Enabled:=SR.Checked;
  end;

  procedure TPrintForm.BtnPrvIEwClick(Sender: TObject);//預覽按鈕單擊事件
  begin
    QuickRep.PrevIEw;
  end;

  procedure TPrintForm.BtnSetClick(Sender: TObject); //設置按鈕單擊事件
  begin
    QuickRep.PrinterSetup;
  end;

  procedure TPrintForm.PsChange(Sender: TObject);//紙張類型改變事件
  begin
    QuickREp.Page.PaperSize:=PaperSize[Ps.ItemIndex];
    PaperH.Text:=FormatFloat('0.00',QuickRep.Page.Length);
    PaperW.Text:=FormatFloat('0.00',QuickRep.Page.Width);
    PaperH.Enabled:=Ps.ItemIndex=26;
    PaperW.Enabled:=Ps.ItemIndex=26;
    CrtRep.Enabled:=True;
    BtnPrint.Enabled:=not CrtRep.Enabled;
    BtnPrvIEw.Enabled:=BtnPrint.Enabled;
  end;

  procedure TPrintForm.PaperChange(Sender: TObject);//紙張寬度和長度改變事件
  begin
    QuickRep.Page.Width:=StrToFloat(PaperW.Text);
    QuickRep.Page.Length:=StrToFloat(PaperH.Text);
  end;

  procedure TPrintForm.FormClose(Sender: TObject; var Action: TCloseAction);
  begin
    Action:=caFree;
  end;

  procedure TPrintForm.FormDestroy(Sender: TObject);
  begin
    ClearRep;
    PrintForm:=nil;
  end;

  procedure TPrintForm.CreateReport(Sender: TObject);//生成按鈕單擊事件
  Var
    I,L:Byte;
    CHBtp,CHBlf,Cd,ObWidth:Word;
  begin
    Screen.Cursor:=crHourGlass;
    Title.Caption:=Bt;//設置標題
    ClearRep(); //清除已經建立的對象;
    if Sr.Checked then QrSQL.Caption:=CXTJ else QRSQL.Caption:=';//是否打印查詢條件?
    CHBtp:=HB.Height-17;//建立的控件在帶區中的頂部位置
    CHBlf:=0; //建立的控件在帶區中的左邊位置
    ObWidth:=0; //建立的控件的寬度
    for I := 0 to Query.FIEldCount-1 do    //根據Query返回字段數建立控件
    begin
  if (Query.Fields[I].DataType<>ftBlob) And (Query.FIElds[I].DataType<>ftMemo) then    
  begin    //忽略備注字段和相片字段
        L:=Query.FIElds[I].DataSize-1;//L=字段寬度(字節)-1
        case Rd1 of   //根據選擇的對齊方式設置控件的對齊方式
          0: if L<=10 then Dj:=taCenter else DJ:=taLeftJustify;
          //自動對齊:字段小於等於10居中對齊,否則左邊對齊
          1: Dj:=taCenter;//居中對齊
          2: DJ:=taLeftJustify;//左邊對齊
        end;
        case Rd2 of    //根據選擇的列表寬度設置報表列寬度
          0: begin    
         //自動寬度:如果L>14則寬度ObWidth=14+(L-14)/2;如果ObWidth
         //的寬度不能顯示列標題,則ObWidth=列標題寬度;如果字段類型
         //為日期型、貨幣型和浮點數型,則ObWidth=65
               if L>14 then L:=14+(L-14) div 2;
               ObWidth:=L*6;
               L:=Length(Query.FIElds[I].DisplayName);
               if ObWidth<L*6 then ObWidth:=L*6;
               ObWidth:=ObWidth+2;
               if (Query.FIElds[I].DataType=ftDateTime) or
                  (Query.FIElds[I].DataType=ftFloat) or
                  (Query.FIElds[I].DataType=ftCurrency) then ObWidth:=65;
             end;
          1: if ColWd.Text<>' then ObWidth:=StrToInt(ColWd.Text)
                else ObWidth:=100;//相同寬度:ObWidth=輸入寬度值
          2: begin  //限制最大寬度:首先按自動寬度計算再判斷寬度是否超最大值,
                    //如果超過則ObWidth=最大寬度輸入值
               if ColWd.Text<>' then Cd:=StrToInt(ColWd.Text)
                  else Cd:=200;
               ObWidth:=L*6;
               if ObWidth>Cd then ObWidth:=Cd;
               ObWidth:=ObWidth+2;
               if (Query.FIElds[I].DataType=ftDateTime) or
                  (Query.FIElds[I].DataType=ftFloat) or
                  (Query.FIElds[I].DataType=ftCurrency) then ObWidth:=65;
             end;
        end;

        if CHBlf+ObWidth>=HB.Width then begin  //建立控件>紙寬?
          DlgMes:='紙張寬度不夠,請更改紙張尺寸。';
          MessageBox(Handle,DlgMes,Cap_Inf,Ico_Inf);
          break;
        end
        else begin
          CHBShape[I]:=TQRShape.Create(HB);//建立列標頭帶區線條控件
          CHBShape[I].Parent:=HB;
          CHBShape[I].Top:=CHBtp;
          CHBShape[I].Left:=CHBlf;
          CHBShape[I].Width:=ObWidth+1;
          CHBShape[I].Height:=17;

          CHBNAME[I]:=TQRLabel.Create(HB); //建立列標題控件
          CHBNAME[I].Parent:=HB;
          CHBNAME[I].Top:=CHBtp+2;
          CHBNAME[I].Left:=CHBlf+1;
          CHBNAME[I].AutoSize:=False;
          CHBNAME[I].Width:=ObWidth-1;
          CHBNAME[I].Alignment:=taCenter;
          CHBNAME[I].Caption:=Query.FIElds[I].DisplayName;//取字段作為列名
          CHBNAME[I].BringToFront;

          DBShape[I]:=TQRShape.Create(DB); //建立細節帶區線條控件
          DBShape[I].Parent:=DB;
          DBShape[I].Top:=-1;
          DBShape[I].Left:=CHBlf;
          DBShape[I].Width:=ObWidth+1;
          DBShape[I].Height:=17;

          DBNAME[I]:=TQRDBText.Create(DB); //建立細節帶區控件
          DBNAME[I].Parent:=DB;
          DBNAME[I].ParentReport:=QuickRep;
          DBNAME[I].Top:=2;
          DBNAME[I].Left:=CHBlf+2;
          DBNAME[I].AutoSize:=False;
          DBNAME[I].Width:=ObWidth-3;
          DBNAME[I].Height:=13;
          DBNAME[I].Alignment:=Dj;
          DBNAME[I].DataSet:=Query;
          DBNAME[I].DataField:=Query.Fields[I].FIEldName;
          DBNAME[I].BringToFront;

          if Tj1.Checked then begin  //是否建立頁腳帶區?
            FBShape[I]:=TQRShape.Create(FB); //建立頁腳帶區線條控件
            FBShape[I].Parent:=FB;
            FBShape[I].Top:=0;
            FBShape[I].Left:=CHBlf;
            FBShape[I].Width:=ObWidth+1;
            FBShape[I].Height:=17;

            if (Query.FIElds[I].DataType=ftFloat) or
               (Query.FIElds[I].DataType=ftCurrency) or (I<2) then
            begin //如果字段類型為數值類型則建立
              FBNAME[I]:=TQRExpr.Create(FB); //建立頁腳帶區控件
              FBNAME[I].Parent:=FB;
              FBNAME[I].ParentReport:=QuickRep;
              FBNAME[I].Top:=3;
              FBNAME[I].Left:=CHBlf+2;
              FBNAME[I].AutoSize:=False;
              FBNAME[I].Width:=ObWidth-3;
              FBNAME[I].Height:=13;
              FBNAME[I].Alignment:=taCenter;
              FBNAME[I].Expression:='SUM(QUERY.'+Query.Fields[I].FIEldName+')';
              FBNAME[I].BringToFront;
            end;
          end;

          if Tj2.Checked then begin  //是否建立總和帶區?
            SumShape[I]:=TQRShape.Create(SB); //建立總和帶區線條控件
            SumShape[I].Parent:=SB;
            SumShape[I].Top:=0;
            SumShape[I].Left:=CHBlf;
            SumShape[I].Width:=ObWidth+1;
            SumShape[I].Height:=17;

            if (Query.FIElds[I].DataType=ftFloat) or
               (Query.FIElds[I].DataType=ftCurrency) or (I<2) then
            begin   //如果字段類型為數值類型則建立
              SumNAME[I]:=TQRExpr.Create(SB);  //建立總和帶區控件
              SumNAME[I].Parent:=SB;
              SumNAME[I].ParentReport:=QuickRep;
              SumNAME[I].Top:=3;
              SumNAME[I].Left:=CHBlf+2;
              SumNAME[I].AutoSize:=False;
              SumNAME[I].Width:=ObWidth-3;
              SumNAME[I].Height:=13;
              SumNAME[I].Alignment:=taCenter;
              SumNAME[I].Expression:='SUM(QUERY.'+Query.Fields[I].FIEldName+')';
              SumNAME[I].BringToFront;
            end;
          end;
          CHBlf:=CHBlf+ObWidth;//當前字段處理完成,往右一個字段寬度
        end;
      end;
    end;
    CrtRep.Enabled:=False;//禁上生成按鈕
    BtnPrint.Enabled:=not CrtRep.Enabled;允許打印铵鈕
    BtnPrvIEw.Enabled:=BtnPrint.Enabled;允許預覽按鈕
    if Tj1.Checked then begin  //如果建立了頁腳帶區,則將頁腳帶區中前兩列更改
      FBNAME[0].Expression:=''頁合計'';
      FBNAME[1].Expression:='COUNT+'行'';
    end;
    if Tj1.Checked then begin  //如果建立了總和帶區,則將總和帶區中前兩列更改
      SumNAME[0].Expression:=''總計'';
      SumNAME[1].Expression:='COUNT+'行'';
    end;
    //調整列標頭帶區中的日期及頁碼打印位置
    QRE2.Left:=HB.Width-Qre2.Width;
    QRSQL.Left:=QRE1.Width+10;
    QRSQL.Width:= QRE2.Left-10-QRSQL.Left;
    QuickRep.DataSet:=Query;  //為QuickRep指定數據集,該句一定不能少
    Screen.Cursor:=crDefault;
  end;

  procedure TPrintForm.ClearRep();//清除生成報表格式時建立的控件
  Var
    I:Byte;
  begin
    For I:=0 to Query.FIEldCount-1 do  begin
      if Assigned(CHBShape[I]) then begin CHBShape[I].Free;CHBShape[I]:=nil;end;
      if Assigned(CHBNAME[I]) then begin CHBNAME[I].Free;CHBNAME[I]:=nil;end;
      if Assigned(DBShape[I]) then begin DBShape[I].Free;DBShape[I]:=nil;end;
      if Assigned(DBNAME[I]) then begin DBNAME[I].Free;DBNAME[I]:=nil;end;
      if Assigned(FBShape[I]) then begin FBShape[I].Free;FBShape[I]:=nil;end;
      if Assigned(FBNAME[I]) then begin FBNAME[I].Free;FBNAME[I]:=nil;end;
      if Assigned(SumShape[I]) then begin SumShape[I].Free;SumShape[I]:=nil;end;
      if Assigned(SumNAME[I]) then begin SumNAME[I].Free;SumNAME[I]:=nil;end;
    end;
  end;

  procedure TPrintForm.SRClick(Sender: TObject);
  begin
    if Sr.Checked then QrSQL.Caption:=CXTJ else QRSQL.Caption:=';
  end;

  procedure TPrintForm.FormShow(Sender: TObject);  //窗體顯示事件
  begin
    Query.Active:=True;//打印SQL
    TT.Text:=Bt;
    QuickRep.ReportTitle:=Bt;//設置標題
    //控件名數組分配空間
    SetLength(CHBNAME,Query.FIEldCount);
    SetLength(CHBShape,Query.FIEldCount);
    SetLength(DBNAME,Query.FIEldCount);
    SetLength(DBShape,Query.FIEldCount);
    SetLength(FBNAME,Query.FIEldCount);
    SetLength(FBShape,Query.FIEldCount);
    SetLength(SumNAME,Query.FIEldCount);
    SetLength(SumShape,Query.FIEldCount);
  end;

  procedure TPrintForm.PaperSizeChg(Sender: TObject);
  begin
    CrtRep.Enabled:=True;
    BtnPrint.Enabled:=not CrtRep.Enabled;
    BtnPrvIEw.Enabled:=BtnPrint.Enabled;
  end;

  procedure TPrintForm.DJChage(Sender: TObject);//對齊方式改變事件處理
  var
    Chg:Byte;
  begin
    if Djauto.Checked then Chg:=0
      else if DjCenter.Checked then Chg:=1
        else Chg:=2;
    if Chg<>Rd1 then begin PaperSizeChg(nil);Rd1:=Chg;end;
  end;

  procedure TPrintForm.WdChage(Sender: TObject);//寬度改變事件處理
  var
    Chg:Byte;
  begin
    if Wdauto.Checked then Chg:=0
      else if Wdall.Checked then begin
                                   Chg:=1;
                                   if ColWd.Text=' then ColWd.Text:='100';
                                 end
        else begin
           Chg:=2;
           if ColWd.Text=' then ColWd.Text:='200';
        end;
    if Chg<>Rd2 then begin PaperSizeChg(nil);Rd2:=Chg;end;
    ColWd.Enabled:=Chg<>0;
  end;

  procedure TPrintForm.QuickRepStartPage(Sender: TCustomQuickRep);
  //報表打印開始新頁事件處理,頁腳帶區中的統計值清空
  Var
    I:Byte;
  begin
  if Tj1.Checked then
    For I:=0 to Query.FIEldCount-1 do
      if Assigned(FBNAME[I]) then FBNAME[I].Reset;
  end;

  procedure TPrintForm.BtnPrintClick(Sender: TObject);
  begin
    QuickRep.Print;
  end;
  end.
  4、 調用對話框舉例:
  首先在將要調用的窗體中的USES語句中包含PrintDlg單元,然後可以用如下代碼調用:
  if not assigned(PrintForm) then PrintForm:=TPrintForm.Create(Application);
  PrintForm.Query.SQL.Assign(Query.SQL);
  //如果調用窗體不包含Query控件,可直接設置SQL語句的值
  PrintForm.Bt:=報表標題;
  PrintForm.Caption:=窗體標題;
  PrintForm.CXTJ:=查詢條件;
  PrintForm.ShowModal;
  5、 結束語
  此程序關鍵是CreateReport事件過程和動態控件名稱的處理。由於編幅所限,有些內容沒有說明,希望讀者自行體會。對於一般的報表生成,此程序能夠滿足要求。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved