Как заставить Client DataSet пересчитать вычисленные и внутренние вычисляемые поля?
У меня есть ClientDatSet
с несколькими fkInternalCalc
поля. CDS не связан ни с одним провайдером; вместо этого он заполняется на лету. Как я могу заставить CDS пересчитать все "вычисляемые" поля? Я не могу позвонить Refresh()
потому что нет поставщика для обновления данных. Единственный способ, с которым я пришел, - это просмотреть все записи, что не является лучшим способом.
PS: я прочитал этот вопрос и этот пост, но я надеюсь на более элегантный способ.
2 ответа
Я добиваюсь этого с помощью помощника (лишенного здесь необходимого), который позволяет вызывать защищенные методы без какого-либо взлома. Обязательно проверьте наличие DataSet.State = dsInternalCalc
внутри OnCalcFields для полей fkInternalCalc.
type
TClientDataSetHelper = class helper for TClientDataSet
public
function AssureEditing: Boolean;
procedure InternalCalc;
end;
function TClientDataSetHelper.AssureEditing: Boolean;
begin
result := not (State in [dsEdit, dsInsert]);
if result then
Edit;
end;
procedure TClientDataSetHelper.InternalCalc;
var
needsPost: Boolean;
saveState: TDataSetState;
begin
needsPost := AssureEditing;
saveState := setTempState(dsInternalCalc);
try
RefreshInternalCalcFields(ActiveBuffer);
finally
RestoreState(saveState);
end;
if needsPost then
Post;
end;
Это можно легко расширить для нормальных вычисляемых полей, используя CalculateFields
, Хотя в этом нет необходимости, поскольку вычисляемые поля пересчитываются при изменении любых других полей данных.
Это немного взломать, но это работает!
DBGrid.Height := 30;
DBGrid.Height := 200; // Refresh all Rows after first
CalculatedProc(DataSet); // Refresh first calculated fields. (Write name of your calculate procedure)