То, что вы хотите, сделать просто, но вы должны быть осторожны, как вы это делаете.
Оставив на время аспект графического интерфейса в стороне, вы хотите добавить вычисляемый столбец в свой TAdoDataSet и инициализировать его в событии OnCalcFields
. Однако то, что вы НЕ хотите делать, - это вычислять TotalQuantity
в этом случае. потому что а) событие OnCalcFields
будет вызываться для каждой строки в наборе данных И б) выполнение чего-либо внутри события OnCalcFields
, которое перемещает курсор набора данных - например, обход набора данных, как предложено в другом ответе, - будет рекурсивно вызывать событие OnCalcFields
.
Способ избежать этой проблемы рекурсии и избежать выполнения какой-либо дополнительной работы, чем это необходимо, - это вычислять TotalQuantity только при первом открытии таблицы и в любое время, когда ее значение может измениться, то есть при редактировании, вставке или удалении строки. , а затем сохраните результат в поле вашей формы или модуля данных. Есть два основных способа сделать это вычисление: 1) использовать TAdoQuery для выполнения Sql, например «SELECT SUM (Quantity) FROM MyTable», или 2) использовать второй экземпляр TAdoDataSet, открытый в вашей таблице. Желательно, чтобы к этому второму экземпляру не было подключено никаких элементов управления графическим интерфейсом, чтобы его можно было перемещать как можно быстрее без использования DisableControls
и EnableControls
.
Чтобы добавить поле Percentage в свой набор AdoDataSet, дважды щелкните его, чтобы открыть редактор полей, щелкните его правой кнопкой мыши и выберите New field
. Убедитесь, что вы установили Type
на Calculated
.
После настройки GetTotalQuantity
процедуры вам необходимо настроить обработчики событий для ее вызова из событий BeforeOpen, BeforeInsert, BeforeEdit и AfterDelete вашего AdoDataSet.
Затем в событии 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;
Or
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;
После того, как вы добавили вычисляемое поле Percentage в свой AdoDataSet и настроили событие OnCalcFields для набора данных, ваша DBGrid с радостью отобразит его, как и любое другое поле набора данных.
person
MartynA
schedule
18.01.2018