[英]How to make percentage from calculation record divided with summary DBGRID Delphi
I have dbgrid which display column subtotal and column percentage, how to display column percentage from this formula : (subtotal / grandtotal) * 100% ? 我有显示列小计和列百分比的dbgrid,如何从此公式显示列百分比:(小计/总计)* 100%? for detail information please see below picture 有关详细信息,请参见下图
I couldnt modify my SQL, because my SQL is very complicated, so i think solution maybe use calculated field, doesnt it? 我无法修改我的SQL,因为我的SQL非常复杂,所以我认为解决方案可能使用计算字段,不是吗? Could someone help me to solve this problem. 有人可以帮我解决这个问题。 Thanks in advanced. 提前致谢。
The following assumes that your dataset doesn't actually contain the last row you've shown, the one that contains "111077, 100" - if it does, then the steps I show below to calculate the GrandTotal are unnecessary, and you only need to populate the Percent
calculated field, which is trivial. 以下假设您的数据集实际上不包含显示的最后一行,而是包含“ 111077,100”的行-如果包含,那么下面显示的用于计算GrandTotal的步骤是不必要的,您只需要填充琐碎的Percent
计算字段。
If your DataSet is a TClientDataSet
, you can implement the Percent values quite easily using the combination of a TAggregateField
to represent the GrandTotal and a calculated field to represent each data row's contribution towards the GrandTotal. 如果您的数据集是TClientDataSet
,则可以使用TAggregateField
代表GrandTotal和计算字段代表每个数据行对GrandTotal的贡献,很容易地实现Percent值。 See code below. 请参见下面的代码。
If you are not using a TClientDataSet already then you have several options, including 如果尚未使用TClientDataSet,则有几种选择,包括
If your DataSet is of a type which supports aggregate fields
then you can do the equivalent of the code below. 如果您的数据集是支持aggregate fields
的类型,则可以执行以下代码的等效操作。
Use your existing DataSet as the dataset source of a TDataSetProvider
, and use the TDataSetProvider
as the Provider
of a TClientDataSet
and use the TClientDataSet
to supply the data to your grid. 使用现有的DataSet作为TDataSetProvider
的数据集源,并使用TDataSetProvider
作为TClientDataSet
的Provider
,并使用TClientDataSet
将数据提供给网格。
Don't use a TClientDataSet
and/or TAggregateField
and instead do similar to what is shown below with your existing DataSet, but make the Percent field an fkInternalCalc
field if your DataSet type supports it, or an fkCalculated
one if not, omit the GrantTotal TAggregateField
field and calculate the GrandTotal in code. 不要使用TClientDataSet
和/或TAggregateField
,而是使用现有的DataSet进行以下显示,但是如果您的DataSet类型支持,请将Percent字段设置为fkInternalCalc
字段,否则将其设置为fkCalculated
,请省略GrantTotal TAggregateField
字段并在代码中计算GrandTotal。 One way to do this would be to calculate it by a once-only traversal of the dataset ( while not DataSet.Eof ...
) after you open it. 一种方法是打开数据集后,通过一次遍历数据集( while not DataSet.Eof ...
)来计算它。
In the code below, I've created all the fields in code, rather than using the Object Inspector's Fields editor, so you can easily see exactly what are the minimum settings necessary to get a TAggregateField
to work. 在下面的代码中,我已经在代码中创建了所有字段,而不是使用对象检查器的字段编辑器,因此您可以轻松地确切地看到使TAggregateField
起作用所需的最小设置是什么。
Note: I could be wrong but don't think you could get a standard TDBGrid
to display the final, 100%, row of your screenshot. 注意:我可能是错的,但是您认为您无法获得标准的TDBGrid
来显示屏幕快照的最后100%。 Somthething similar could be done using the Developer Express TcxGrid
, amongst others, but if you need a TDBGrid to do this, you should ask how to in a new question. 使用Developer Express TcxGrid
等可以进行类似的操作,但是如果您需要TDBGrid来执行此操作,则应询问如何提出新问题。
Code 码
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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.