你想做的事情很简单,但你需要小心你如何做。
暂时将 gui 方面放在一边,您要做的是添加一个经过计算的
列到您的 TAdoDataSet 并在其OnCalcFields 事件中对其进行初始化。然而,
您不要想要做的是在该事件中计算TotalQuantity。
因为 a) 将为数据集中的每一行调用 OnCalcFields 事件
并且 b) 在 OnCalcFields 事件中做任何事情来移动数据集的光标
- 就像在另一个答案中建议的那样遍历数据集 - 将递归
调用OnCalcFields 事件。
避免这种递归问题并避免做不必要的工作的方法是仅在以下情况下计算 TotalQuantity
表第一次打开,任何时候它的值都可以改变,也就是说,当一行
被编辑、插入或删除,然后将结果保存在表单的字段中
或数据模块。您可以通过两种主要方式进行此计算:1)使用 TAdoQuery
使用第二个实例执行像“SELECT SUM(Quantity) FROM MyTable”或 2) 这样的 Sql
TAdoDataSet 在您的表上打开。最好第二个实例不应该有任何 gui
与之相连的控件,因此可以在没有
必须使用DisableControls 和EnableControls。
要将百分比字段添加到您的 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 将很乐意显示它,就像数据集的任何其他字段一样。