在Delphi DBGrid中计算的百分比

Ste*_*osi 3 delphi ms-access dbgrid tadotable

几天后我一直在维护一个Delphi应用程序.客户想要将一个百分比列添加到DBGrid,现在显示"数量"列.当然,百分比将是行数/总数量*100

我无法修改底层TADOTable,因为它在代码中的其他位置使用,但我尝试将计算字段添加到TADOTable - 但似乎计算字段不能具有基于聚合值(即数量总和)的值.

我成功地向DBGrid添加了一个空列,但有没有办法填充每行中的%值?

Mar*_*ynA 7

你想要的是直截了当的,但你需要小心如何做到这一点.

暂时离开gui方面,您要做的是将计算列添加到TAdoDataSet并在其OnCalcFields事件中初始化它.不过,你不要想做的是计算TotalQuantity在该事件中.因为a)OnCalcFields将为数据集中的每一行调用OnCalcFields事件,并且b)在事件内部执行任何移动数据集光标的操作 - 就像在另一个答案中建议的那样遍历数据集 - 将以递归方式调用OnCalcFields事件.

避免这种递归问题的方法,以及避免做任何必要的工作,只是在第一次打开表时以及任何时候它的值可以改变时,即在编辑,插入或删除行时计算TotalQuantity ,然后将结果保存在表单或数据模块的字段中.有两种主要方法可以进行此计算:1)使用TAdoQuery执行Sql,如"SELECT SUM(Quantity)FROM MyTable"或2)使用 在表上打开的第二个 TAdoDataSet 实例.优选地,该第二实例不应具有与其连接的任何gui控件,因此可以尽可能快地遍历它而不必使用DisableControlsEnableControls.

要将百分比字段添加到AdoDataSet,请双击它以弹出字段编辑器,右键单击它并选择New field.确保将其设置TypeCalculated.

一旦你有你GetTotalQuantity的程序设置,您需要设置事件处理程序,从您的AdoDataSet的BeforeOpen,BeforeInsert,BeforeEdit和AfterDelete事件调用它.

然后在您的OnCalcFields事件中,计算并分配计算到的百分比值.

完成所有这些操作所需的代码非常简单,例如

procedure TForm1.GetTotalQuantity;
begin
  //  AdoQuery1 contains Sql to obtain the sum of the AdoDataSet's
  if AdoQuery1.Active then
    AdoQuery1.Close;
  AdoQuery1.Open;
  try
    TotalQuantity := AdoQuery1.Fields[0].AsFloat;  //  TotalQuantity is a field of your for, (or datamodule)
  finally
    AdoQuery1.Close;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

要么

procedure TForm1.GetTotalQuantity;
begin
  //  Note: AdoDataSet2 is a second instance of TAdoDataSet set up to access the same
  //  db table as the one connected to the OP's DBGrid
  if AdoDataSet2.Active then
    AdoDataSet2.Close;
  AdoDataSet2.Open;
  try
    TotalQuantity := 0;
    while not AdoDataSet2.Eof do begin
      TotalQuantity :=  TotalQuantity + AdoDataSet2Quantity.AsFloat; // AdoDataSet2.Quantity.AsFloat;
      AdoDataSet2.Next;
    end;
  finally
    AdoDataSet2.Close;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

OnCalcFields事件:

procedure TForm1.AdoDataSet1CalcFields(DataSet : TDataSet);
begin
  if TotalQuantity > 0 then
    AdoDataSet1Percentage.AsFloat := AdoDataSet1Quantity.AsFloat / Total Quantity * 100;
end;
Run Code Online (Sandbox Code Playgroud)

将百分比计算字段添加到AdoDataSet并为数据集设置OnCalcFields事件后,DBGrid将很乐意显示它,就像数据集的任何其他字段一样.