【问题标题】:How to make percentage from calculation record divided with summary DBGRID Delphi如何从计算记录中得出百分比除以汇总 DBGRID Delphi
【发布时间】:2016-05-12 10:30:04
【问题描述】:

我有显示列小计和列百分比的 dbgrid,如何从这个公式显示列百分比:(小计/总计)* 100%?详情请看下图

我无法修改我的 SQL,因为我的 SQL 非常复杂,所以我认为解决方案可能使用计算字段,不是吗?有人可以帮我解决这个问题。 提前致谢。

【问题讨论】:

  • 尝试在字段编辑器中将计算字段添加到 DBGrid
  • 什么样的 TDataSet 组件向网格提供数据?
  • 我使用 Zeos 组件

标签: delphi dbgrid


【解决方案1】:

以下假设您的数据集实际上不包含您显示的最后一行,即包含“111077, 100”的行 - 如果包含,那么我在下面显示的计算 GrandTotal 的步骤是不必要的,并且您只需要填充Percent 计算字段,这很简单。

如果您的 DataSet 是 TClientDataSet,您可以使用 TAggregateField 的组合表示 GrandTotal 和计算字段以表示每个数据行对 GrandTotal 的贡献。请参阅下面的代码。

如果您还没有使用 TClientDataSet,那么您有多种选择, 包括

  • 如果您的 DataSet 属于支持 aggregate fields 的类型,那么您可以执行以下代码的等效操作。

  • 使用您现有的 DataSet 作为TDataSetProvider 的数据集源,使用TDataSetProvider 作为TClientDataSetProvider,并使用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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 2017-03-09
    相关资源
    最近更新 更多