在Delphi DBGrid

时间:2018-01-18 10:44:12

标签: delphi ms-access dbgrid tadotable

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

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

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

2 个答案:

答案 0 :(得分:7)

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

暂时离开gui方面,你想要做的是添加一个计算 列到您的TAdoDataSet并在其OnCalcFields事件中初始化它。然而, 您想要做的是计算该事件中的TotalQuantity。 因为a)将为数据集中的每一行调用OnCalcFields事件 和b)在移动数据集光标的OnCalcFields事件内做任何事情 - 就像在另一个答案中建议的那样遍历数据集 - 将递归地进行 致电OnCalcFields活动。

避免这种递归问题的方法,以及避免做任何必要的工作,只是计算TotalQuantity时 该表首先打开,任何时候它的值都可以改变,也就是说,当一行时 编辑,插入或删除,然后将结果保存在表单的字段中 或数据模块。您可以通过两种主要方式进行此计算:1)使用TAdoQuery 执行Sql,如“SELECT SUM(Quantity)FROM MyTable”或2)使用第二个实例 在你的桌子上打开了TAdoDataSet。优选地,该第二实例不应具有任何gui 连接到它的控件,因此可以在没有的情况下尽快遍历 必须使用DisableControlsEnableControls

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

设置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;

或者

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;

OnCalcFields事件:

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

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

答案 1 :(得分:-2)

您是否尝试过计算OnCalcFields事件的百分比?不是100%确定以下内容,但此示例可能对您有所帮助:

procedure TClass.DataSetCalcFields(DataSet: TDataSet);
var
  Bookmark: String;
  TotalQuantity: Double;
begin
    // Save current position
    Bookmark := Dataset.Bookmark;

    // Calculate the total quantity in a while loop through the dataset:
    Dataset.First;
    while not Dataset.Eof do
    begin
      TotalQuantity := TotalQuantity + Dataset.FieldByName('QUANTITY').AsFloat;
      Dataset.Next;
    end;

    // Load current position
    Dataset.Bookmark := Bookmark;

    // Calculate the percentage:
    if TotalQuantity > 0 then
    begin
      Dataset.FieldByName('PERCENTAGE').AsFloat := Dataset.FieldByName('QUANTITY').AsFloat / TotalQuantity * 100;
    end
    else
    begin
      Dataset.FieldByName('PERCENTAGE').AsFloat := 0;
    end;
  end;
end;