• <label id="pxtpz"><meter id="pxtpz"></meter></label>
      1. <span id="pxtpz"><optgroup id="pxtpz"></optgroup></span>

        當前位置:雨林木風下載站 > 技術開發教程 > 詳細頁面

        在Delphi中完成數據區分模塊的動態報表

        在Delphi中完成數據區分模塊的動態報表

        更新時間:2019-06-21 文章作者:未知 信息來源:網絡 閱讀次數:

        一、問題的提出

        ---- Delphi作為強大的數據庫開發工具,正被愈來愈多的編程人員所采用,"聰明的程序員用Delphi"更形象生動的道出廣大程序員的心聲,但這并不意味著所有功能的實現都非常容易,例如,筆者在開發軍隊的某個信息系統中,就在為數據分析模塊中DecisionGrid1控件的數據進行報表輸出時走了不少的彎路。廣大的Delphi的愛好者在今后的學習或工作中也有可能會遇到類似的問題,而在許多參考書中,很少有甚至沒有關于它們的解決方法,于是,我想花費一點時間把它整理出來,以供大家參考。本文中報表動態生成的公用模塊具有很大的靈活性和易操作性,其中的思路、實現的功能和通用性等方面的優缺點就由大家看了本文后自有定論。

        二、建立報表的動態輸出公用模塊

        ---- 下面,結合公司人事管理信息系統說明其實現的方法和技術。

        ---- 1、基本思路:首先從DecisionGrid1中獲得報表所需數據,放到二維數組PA中,然后在C:\DataWork中動態創建一個數據表tjb.dbf,存放報表數據,最后用T able1與tjb.dbf相連接,以后工作就與一般的動態輸出報表(如查詢報表)相類似,在這里我就無須贅述了。

        ---- 2、建立窗體文件:放入六個用于數據分析的常用控件DecisionQuery1、DecisionSource1、DecisionCube1、DecisionGraph1、DecisionPivot1、DecisionGrid1,設置DecisionSource1的decisionCube屬性為decisionCube1,decisionCube1的Dataset屬性為decisionQuery1、decisionQuery1的DatabaseName屬性為c:\datawork;一個Table1控件,用于連接數據表tjb.dbf;一個QuickRep1控件,用于數據的報表輸出;兩個Button1和Button2控件,其Caption分別設為"報表輸出"和"返回"。分別設置decisionCube1的Dataset屬性為decisionQuery1、decisionQuery1的DatabaseName屬性為c:\datawork.。

        ---- 3、單元文件的主要控件代碼 Button1控件的代碼如下(定義變量部分略),主要分以下8個功能塊來加以說明:

        ---- ⑴刪除同名或上一次建立的數據表

        if FileExists('c:\DataWork\tjb.dbf') then
        deletefile('c:\ DataWork \tjb.dbf');

        ---- ⑵根據DecisionGrid1控件的cells屬性,獲得報表所需數據,并將其默認的'Sum'值漢化成'總計'、'合計'、'小計'以符合漢語的習慣要求,所求得的數據存放于二維數組PA中
        for i:=1-DecisionGrid1.FixedCols to DecisionGrid1.
        ColCount-DecisionGrid1.FixedCols-1 do
        for j:=0-DecisionGrid1.FixedRows to DecisionGrid1.
        RowCount-DecisionGrid1.FixedRows-1 do
        begin
        pa[i,j]:=DecisionGrid1.cells[i,j];
        //處理DecisionGrid1控件中固定列的值為'Sum'的數據項
        if ((i=1-DecisionGrid1.fixedcols) and (pa[i,j]='Sum')) then
        pa[i,j]:='總 計'
        else if ((i = -1) and (pa[i,j]='Sum')) then
        pa[i,j]:='小 計'
        else if ((i<-1) and (i>1-DecisionGrid1
        .FixedCols) and (pa[i,j]='Sum')) then
        pa[i,j]:='合 計';
        //處理DecisionGrid1控件中固定行的值為'Sum'的數據項
        if (pa[i,j]='Sum' ) and (j=-1) then
        pa[i,j]:='總 計';
        end;

        ---- ⑶用T able1動態創建數據表tjb.dbf
        Table1.Active:=false;
        with Table1 do
        begin
        DatabaseName := 'c:\DataWork';
        TableName := 'tjb';
        TableType := ttDBase;
        with FieldDefs do
        begin
        Clear;
        for i:=1 to 40 do
        Add(IntToStr(i),ftString,30, False);
        end;
        CreateTable;
        end;
        //下面將DecisionGrid1控件中的數據放入數據表中
        Table1.Active:=true;
        for j:=1-DecisionGrid1.FixedRows to DecisionGrid1
        .RowCount-DecisionGrid1.FixedRows-1 do
        begin
        K:=0;
        Table1.Insert;
        for i:=1-DecisionGrid1.FixedCols to DecisionGrid1
        .ColCount-DecisionGrid1.FixedCols-1 do
        begin
        Table1.Fields[K].AsString:=pa[i,j];
        K:=K+1;
        end;
        Table1.Post;
        Table1.Next;
        end;

        ---- ⑷下面代碼確定輸出報表的每列寬度
        SetLength(M,DecisionGrid1.ColCount);//動態設置數組
        copy(M,1-DecisionGrid1.FixedCols,DecisionGrid1
        .ColCount-DecisionGrid1.FixedCols-1);
        //重新設置動態數組的起始位置
        for i:=1-DecisionGrid1.FixedCols to DecisionGrid1
        .ColCount-DecisionGrid1.FixedCols-1 do
        begin
        M[i]:=0;
        for j:=1-DecisionGrid1.FixedRows to DecisionGrid1
        .RowCount-DecisionGrid1.FixedRows-1 do
        IF M[i]< Length (Trim (PA[I,J]))*8 THEN
        M[i]:= Length (Trim (PA[I,J]))*8;
        end;

        ---- ⑸如果要求輸出報表的列寬相同(除DecisionGrid1控件的固定列,下同),可將數據項的最大列寬作為輸出報表的列度,如果不要求,可跳過下面代碼
        max:=0;
        for i:=0 to DecisionGrid1.ColCount
        -DecisionGrid1.FixedCols-1 do
        if m[i]>max then
        max:=m[i];
        for i:=0 to DecisionGrid1.ColCount
        -DecisionGrid1.FixedCols-1 do
        m[i]:=max;
        ZK:=0;//報表總寬
        for i:=1-DecisionGrid1.FixedCols to DecisionGrid1
        .ColCount-DecisionGrid1.FixedCols-1 do
        ZK:=ZK+M[i]+1;

        ---- ⑹判斷報表的寬度,超寬?橫向報表?還是縱向報表?
        if ZK>1123 then
        begin
        Application.MessageBox('報表超寬,
        請調整再輸出!','警告', 1);//輸出對話框
        exit;
        end
        else if ZK>794 then
        QuickRep.Page.Orientation:=poLandscape //橫向
        else
        QuickRep.Page.Orientation:=poPortrait;//縱向

        ---- ⑺以下代碼完成了動態數據報表,與一般的動態輸出報表功能相類似,
        for i:=1 to QuickRep.Bands.TitleBand.
        ControlCount DO//取消系統對控件的控制,下同
        QuickRep.Bands.TitleBand.RemoveControl
        (QuickRep.Bands.TitleBand.Controls[0]);
        for i:=1 to QuickRep.Bands.DetailBand.ControlCount DO
        QuickRep.Bands.DetailBand.RemoveControl
        (QuickRep.Bands.DetailBand.Controls[0]);
        SetLength(QRShape,DecisionGrid1.ColCount)
        ; //動態設置數組
        SetLength(QRDBText, DecisionGrid1.ColCount)
        ; //動態設置數組
        K:=0;//動態生成對象的數,
        Lx:=(QuickRep.Width-ZK)DIV 2;//生成對象的左坐標
        //報表的動態生成
        For j:=1-DecisionGrid1.FixedCols to DecisionGrid1
        .ColCount-DecisionGrid1.FixedCols-1 do
        begin
        QRShape[K]:=TQRSHAPE.Create(tj1);//自定義對象的創建(下同)
        QRShape[K].Parent:=QuickRep.Bands
        .DetailBand;// 自定義對象的父類對象(下同)
        QRDBText[K]:=TQRDBText.Create(tj1);
        QRDBText[K].parent :=QuickRep.Bands.DetailBand;
        QRShape[K].LEFT:=Lx;//生成對象的左坐標
        QRShape[K].WIDTH:=M[J]+2; //生成對象的寬度
        QRShape[K].HEIGHT:=QuickRep.Bands
        .DetailBand.Height+1; //生成對象的高度
        QRShape[K].TOP:=-1; //生成對象的縱坐標
        QRDBText[K].WIDTH:=QRShape[K].WIDTH-10;
        QRDBText[K].Left :=QRShape[K].LEFT+1;
        QRDBText[K].HEIGHT:=QRShape[K].Height div 2;
        QRDBText[K].Top :=QRDBText[K]
        .Height div 2+QRShape[K].Top;
        QRDBText[K].AutoSize:=false;
        QRDBText[K].Alignment:=taCenter; //生成對象居中
        QRDBText[K].DataSet:=Table1;
        QRDBText[K].DataField:=IntToStr(k+1);
        Lx:=Lx+M[J]+1;
        Inc(k);
        end;
        //動態生成報表的標題
        Caption := TQRLabel.Create(tj1);
        Caption.Parent := QuickRep.Bands.TitleBand;
        Caption.Alignment:=taCenter;//標題居中
        Caption.Width:= Length (Trim (ptitle))*8; //標題的寬度
        Caption.Left:=(QuickRep.Width-
        Length (Trim (ptitle))*8)div 2; //標題的左坐標
        Caption.Height:=QuickRep.Bands
        .TitleBand.Height-1; //標題的高度
        Caption.Top:= 0;
        Caption.Caption:=ptitle; //標題的名稱
        ,ptitle為調用該公用模塊時的輸入參數
        QuickRep.DataSet:=Table1;
        QuickRep.Preview;
        ⑻動態生成對象的內存釋放
        k:=0;
        for j:=1-DecisionGrid1.FixedCols to DecisionGrid1
        .ColCount-DecisionGrid1.FixedCols-1 do
        begin
        QRShape[K].Free;
        QRDBText[K].Free;
        inc(k);
        end;
        Caption.Free;
        Table1.Active:=false;//關閉數據表
        end;

        ---- 以上程序是在Delphi 4.0中調試通過,其數據文件應放在C:\DataWork,類型為DB或DBF。
        三、應注意以下幾個問題

        ---- 1、QuickRep1的Bands中的HasColumnHeader、HasDetail、HasTitle三個屬性必須設置為true;

        ---- 2、不能忘記公用模塊中QuickRep對象的DataSet屬性設置,即源代碼中的QuickRep.DataSet:=Table1語句;

        ---- 3、動態生成組件的寬度計算必須放在定義其字體屬性完成后進行;

        ---- 4、另外,動態數組給定的內存(即數組容量)以及指定動態數組的起始位置(不一定為0,根據DecisionGrid1控件的固定列確定)很重要,因為一方面當數據庫很大時它會大大減少內存的消耗,另一方面便于操作該數組,大大增強了程序的靈活性和通用性。

        ---- 5、如果讓QRDBText控件的數據居中,必須先設置其AutoSize屬性為false,然后才能設置其Alignment屬性為taCenter。這一點往往容易忽略,直接設置Alignment屬性為taCenter,往往達不到數據居中的目的。

        四、結束語

        ---- 當然,由于客戶對數據報表的可能特殊要求,此公用模塊或許不能完全解決。但是,作為公用模塊,能實現實現代碼的重復利用,提高我們開發程序的效率,當然可以在此模塊的基礎上進行一些修改或補充,以滿足大多數用戶的要求,用以下兩點加以說明。

        ---- 1、如果要對數據表的字段進行動態選擇輸出,則可以將動態產生的數據表字段傳遞到另一個窗體進行輸出選擇,然后根據你所選擇的字段進行報表輸出,源程序幾乎無須修改即可實現。

        ---- 2、若要改變數據分析的內容(即直方圖的維)時,只須修改SQL語句即可,動態、靜態均可,具體的操作也就無須我多言了。各位Delphi編程愛好者不妨一試。

        溫馨提示:喜歡本站的話,請收藏一下本站!

        本類教程下載

        系統下載排行

        主站蜘蛛池模板: 日韩电影免费在线观看| 高潮毛片无遮挡高清免费视频| 久久er国产精品免费观看8| 午夜男人一级毛片免费| 亚洲男同gay片| 国产精品免费视频一区| 美女的胸又黄又www网站免费| 亚洲?V无码乱码国产精品| 国产AV日韩A∨亚洲AV电影| 国产一级一片免费播放i| 黄色a级免费网站| 国产亚洲色婷婷久久99精品91| 曰韩无码AV片免费播放不卡| 亚洲无码日韩精品第一页| 韩国免费A级毛片久久| 亚洲AV日韩AV永久无码下载| 日韩精品无码一区二区三区免费| 亚洲综合无码一区二区| 18观看免费永久视频| 亚洲一区二区三区在线网站 | 免费看一区二区三区四区| 亚洲成人午夜在线| 手机看黄av免费网址| 亚洲av永久无码一区二区三区| 国产午夜影视大全免费观看| jizz免费观看视频| 亚洲伦另类中文字幕| 日韩吃奶摸下AA片免费观看 | 国产成人亚洲精品播放器下载| 国产在线ts人妖免费视频| 一区二区三区免费看| 亚洲一区二区在线视频| 免费高清在线影片一区| 色吊丝性永久免费看码| 婷婷亚洲久悠悠色悠在线播放| 一个人免费观看www视频在线| 免费人妻精品一区二区三区| 亚洲视频在线观看| 国产特级淫片免费看| 久久免费视频精品| 亚洲成a人无码亚洲成www牛牛|