Delphi 如何用汇总DBGRID对计算记录进行百分比划分

iezvtpos  于 2023-10-18  发布在  其他
关注(0)|答案(1)|浏览(152)

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

我不能修改我的SQL,因为我的SQL是非常复杂的,所以我认为解决方案可能使用计算字段。

rkttyhzu

rkttyhzu1#

下面假设你的数据集实际上并不包含你所显示的最后一行,即包含“111077,100”的那一行-如果它包含,那么我下面显示的计算GrandTotal的步骤是不必要的,你只需要填充Percent计算字段,这是微不足道的。
如果您的数据集是TClientDataSet,您可以很容易地实现百分比值,使用TAggregateField表示GrandTotal,并使用计算字段表示每个数据行对GrandTotal的贡献。请参见下面的代码。
如果您还没有使用TClientDataSet,那么您有几个选项,包括

  • 如果您的数据集是支持aggregate fields的类型,则可以执行与下面代码等效的操作。
  • 使用现有的数据集作为TDataSetProvider的数据集源,使用TDataSetProvider作为TClientDataSetProvider,并使用TClientDataSet将数据提供给网格。
  • 不要使用TClientDataSet和/或TAggregateField,而是对现有的数据集执行类似于下面所示的操作,但是如果数据集类型支持,则将Percent字段设置为fkInternalCalc字段,如果不支持,则将Percent字段设置为fkCalculated字段,忽略GrantTotal TAggregateField字段并在代码中计算GrandTotal。一种方法是在打开数据集(while not DataSet.Eof ...)后,通过对数据集进行一次遍历来计算它。

在下面的代码中,我已经在代码中创建了所有字段,而不是使用Object Inspector的Fields编辑器,因此您可以轻松地看到让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;

相关问题