How is it possible to manually execute the "OnCalcFields" event?
Asked Answered
A

3

4

Say that I temporarily want to disable the OnCalcFields event (eg. by setting cdsCalcFields := nil) during a time-consuming operation on a TClientDataSet. How can I tell the TClientDataSet to perform a recalculation of the calculated fields when I re-attach the OnCalcFields method?

Another situation that might require a manual recalculation is the situation where some of the calculated fields are depending on other datasets (eg. a calculated field is used to temporarily hold some aggregated value from the other dataset). This would work fine in most cases because the OnCalcFields events are executed often enough to get the correct value from the other dataset. But in some circumstances a recalculation is necessary to obtain the correct value from the other dataset.

Setting the AutoCalcFields property to False might also get you into some situation where a manual recalculation is desired.

I've seen several explanations on how to reduce the execution of the OnCalcFields event, but I can't find a simple way to just perform a recalculation...

Any suggestions?

Amalle answered 26/5, 2011 at 10:21 Comment(6)
It seems that your question is wrong. You don't want to execute this OnCalcFields event. Instead you appear to want to recalculate the fields. Thus my rather daft answer, now deleted.Buiron
@David - Perhaps I'm the one who misunderstood... Now thinking about it, it is even not evident if the re-calc is requested on only one record or the whole recordset.Rustic
@David, I guess you're right on the formulation part. But the only place to assign values to the calculate fields is in the OnCaldFields event.Rasheedarasher
@Sertac: My main concern is on the active record, so @David's answer was relevant indeed.Rasheedarasher
@David - Considering @Jorn's comment you might like to undelete your answer.Rustic
@Sertac I think I'll leave it deleted. I don't know anything about the data side of things. I do know how to fire events, and so, whilst my answer covers the question as asked, I don't feel too comfortable with it.Buiron
R
6

Calculated fields are calculated when records are retrieved from the database, so call Refresh (or Close -> Open) on the dataset to force a re-calculation.

(Regarding the comments on the question), to force a re-calculation on only one record you can call RefreshRecord on the dataset. If the particular dataset descendant does not implement the method, an Edit followed by a Cancel call would achieve the same.

Rustic answered 26/5, 2011 at 10:52 Comment(2)
I think the cds.Edit; cds.Cancel;-combination is the solution closest to what I'm looking for. The Refresh-methods involves a re-read from the underlying DB, and that is not preferable.Rasheedarasher
@Jorn - The Cancel method synchronizes with the database so it involves a re-read. The only possible solution not involving a data retrieval I can think of, involves a call to a protected method: THackCDS(cds).GetCalcFields(cds.ActiveBuffer); where THackCDS=class(TClientDataSet). I'm not putting this into the answer since I haven't done enough testing.Rustic
G
2

Calling Refresh or Close-> can cause the entire table to reload from the database. If this isn't something you want you can just call the OnCalc method your self passing it the CDS. Though you may have to slide the cursor manually.

with DisplayAcctListCDS do begin
  First;
  while not Eof do begin
    Edit;
    DisplayAcctListCDSCalcFields(DisplayAcctListCDS);
    Next;
  end;
end;

Assuming DisplayAcctListCDS is your TClientDataSet with calculated fields and DisplayAcctListCDSCalcFields is the generated event method for OnCalcFields.

Garica answered 6/12, 2011 at 17:26 Comment(1)
+1 - I don't think that I would use this in a "general" case, but it worked as a private method in a TDataSet descendent very nicely.Chianti
M
0

This is a bit of a hack, but 100% of answer on this qestion for me!

DBGrid.Height := 30; 
DBGrid.Height := 200; // Refresh all Rows after first
CalculatedProc(DataSet); // Refresh first calculated fields. (Write name of your calculate procedure)
Melitta answered 17/9, 2017 at 12:11 Comment(5)
Why don't you call "refresh" if you want to refresh all rows?Rustic
Refresh reload data from server.Melitta
And where do you think the record buffer is retrieved when you increase grid's height?Rustic
When the window of grid is redrawn, the calculated fields are recalculatedMelitta
The code in your answer reloads data from server. So it's better to call "refresh". One obvious advantage in using "refresh" is it doesn't need a grid.Rustic

© 2022 - 2024 — McMap. All rights reserved.