2016-05-12 56 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

好吧会试试兄弟 –