2016-05-12 60 views
0

我有dbgrid顯示列小計和列百分比,如何顯示列百分比從這個公式:(小計/ grandtotal)* 100%?詳細信息請參考以下圖片如何使計算記錄中的百分比除以彙總DBGRID德爾福

enter image description here

我不能修改我的SQL,因爲我的SQL是非常複雜的,所以我覺得解決方案也許還可以利用計算字段,犯規呢?有人可以幫助我解決這個問題。 謝謝先進。

+0

嘗試添加計算字段中的字段編輯器DBGRID – Marusyk

+1

什麼樣的數據集組件組件是提供數據到網格? – MartynA

+0

我使用Zeos組件 –

回答

4

以下假設您的數據集實際上並不包含您顯示的最後一行,即包含「111077,100」的那一行 - 如果是,則下面顯示的計算GrandTotal的步驟是不必要的,你只需要填充Percent計算的字段,這是微不足道的。

如果數據集是一個TClientDataSet,你可以很容易地使用TAggregateField的 組合來表示GrandTotal和計算字段來表示每個數據行的朝GrandTotal貢獻實現百分比值。見下面的代碼。

如果你不使用的TClientdataSet已經那麼你有幾種選擇,包括

  • 如果數據集是支持aggregate fields那麼你可以做下面的代碼相當於一個類型的。

  • 使用現有的DataSet爲TDataSetProvider的數據集源,並使用TDataSetProviderTClientDataSetProvider,並使用TClientDataSet將數據提供給您的網格。

  • 不要使用TClientDataSet和/或TAggregateField,而是做一些類似的是與您現有的數據集如下所示,但使百分比領域的fkInternalCalc場如果數據集類型支持它,或fkCalculated一個如果不是,請省略GrantTotal TAggregateField字段並在代碼中計算GrandTotal。一種方法是在打開數據集後,通過一次遍歷數據集(while not DataSet.Eof ...)來計算它。

在下面的代碼中,我創建的所有字段的代碼,而不是使用Object Inspector的字段編輯器,這樣你就可以很容易地看到什麼是所需的最低設置,以獲得一個TAggregateField工作。

注:我可能是錯的,但不認爲你可以得到一個標準的TDBGrid來顯示你的截圖的最後一行,100%。可以使用Developer Express TcxGrid等來完成類似的工作,但如果您需要TDBGrid來執行此操作,則應該詢問如何解決新問題。

代碼

TForm1 = class(TForm) 
    CDS: TClientDataSet; 
    DataSource1: TDataSource; 
    DBGrid1: TDBGrid; 
    procedure CDSCalcFields(DataSet: TDataSet); 
    procedure FormCreate(Sender: TObject); 
    private 
    CDSID : TIntegerField; 
    CDSTotal : TCurrencyField; 
    CDSPercent : TFloatField; 
    CDSGrandTotal : TAggregateField; 
    public 
    procedure SetUp; 
    end; 

[...] 

procedure TForm1.SetUp; 
var 
    i : Integer; 
begin 
    CDSID := TIntegerField.Create(Self); 
    CDSID.FieldName := 'ID'; 
    CDSID.FieldKind := fkData; 
    CDSID.DataSet := CDS; 

    CDSTotal := TCurrencyField.Create(Self); 
    CDSTotal.FieldName := 'Total'; 
    CDSTotal.FieldKind := fkData; 
    CDSTotal.DataSet := CDS; 

    CDSPercent := TFloatField.Create(Self); 
    CDSPercent.FieldName := 'Percent'; 
    CDSPercent.FieldKind := fkInternalCalc; 
    CDSPercent.DataSet := CDS; 

    CDSGrandTotal := TAggregateField.Create(Self); 
    CDSGrandTotal.FieldName := 'GrandTotal'; 
    CDSGrandTotal.FieldKind := fkAggregate; 
    CDSGrandTotal.Expression := 'Sum(Total)'; 
    CDSGrandTotal.DataSet := CDS; 
    CDSGrandTotal.Active := True; 

    CDS.OnCalcFields := CDSCalcFields; 
    CDS.IndexFieldNames := 'ID'; 

    CDS.CreateDataSet; 
    for i := 1 to 2 do begin 
    CDS.InsertRecord([i, i]); 
    end; 

    CDS.First; 
end; 

procedure TForm1.CDSCalcFields(DataSet: TDataSet); 
var 
    Value : Double; 
    V : Variant; 
begin 
    V := CDSGrandTotal.Value; 
    if not VarIsNull(V) then begin 
    Value := CDSTotal.AsFloat; 
    Value := Value * 100/V; 
    CDSPercent.Value := Value; 
    end; 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    SetUp; 
end; 
+0

好吧會試試兄弟 –