Board index » delphi » Forcing an OnCalcFields event...

Forcing an OnCalcFields event...


2007-01-10 11:01:20 PM
delphi144
Hi,
Does anyone know how to force an OnCalcFields event to get launched? I
need this ability because I have got a calculated field that depends on
data not in the TDataSet (in a TStringList), so I need to recalculate
its value if ever the contents of the TStringList changes.
I usually just call Edit / Cancel, but since the dataset I am working
with right now is read-only, I was wondering if there's another
solution.
Any ideas?
BTW, I am using the BDE in this application.
--
Best regards,
Jonathan Neve
_______________
CopyTiger - advanced database replicator for Interbase/Firebird!
Web : www.microtec.fr/copycat/ct
_______________________________________
CopyCat - database replication components for Delphi/C++Builder!
Web : www.microtec.fr/copycat/cc
 
 

Re:Forcing an OnCalcFields event...

Jonathan Neve[Microtec] writes:
Quote
Hi,

Does anyone know how to force an OnCalcFields event to get launched? I
need this ability because I have got a calculated field that depends on
data not in the TDataSet (in a TStringList), so I need to recalculate
its value if ever the contents of the TStringList changes.

I usually just call Edit / Cancel, but since the dataset I am working
with right now is read-only, I was wondering if there's another
solution.

Any ideas?

BTW, I am using the BDE in this application.
How about manually? That is,
if (pDataSet->OnCalcFields != NULL)
{
pDataSet->OnCalcFields(this);
}
Best Regards,
Shane
 

Re:Forcing an OnCalcFields event...

"Jonathan Neve[Microtec]" <XXXX@XXXXX.COM>writes news:XXXX@XXXXX.COM...
Quote
Hi,

Does anyone know how to force an OnCalcFields event to get launched? I
need this ability because I have got a calculated field that depends on
data not in the TDataSet (in a TStringList), so I need to recalculate
its value if ever the contents of the TStringList changes.

I usually just call Edit / Cancel, but since the dataset I am working
with right now is read-only, I was wondering if there's another
solution.

Any ideas?

BTW, I am using the BDE in this application.
--
Best regards,
Jonathan Neve
_______________
CopyTiger - advanced database replicator for Interbase/Firebird!
Web : www.microtec.fr/copycat/ct
_______________________________________
CopyCat - database replication components for Delphi/C++Builder!
Web : www.microtec.fr/copycat/cc
Wouldn't calling Dataset.Refresh do the trick?
Andrew
 

Re:Forcing an OnCalcFields event...

Hello Jonathan
Actually, there are no legal ways to recalculate only fields.
I think, Edit & Cancel will be most cheap one.
Regards,
Dmitry
--
Dmitry Arefiev - www.da-soft.com
AnyDAC - Oracle, MySQL, MS SQL, MSAccess, IBM DB2, Sybase
ASA, DbExpress, ODBC freeware data access framework
gs-soft AG - www.gs-soft.com
SAPx - Delphi to SAP R/3 direct access
Saphir - SAP R/3 metadata at your fingertips
MetaBase - ERWIN model in Delphi applications
 

Re:Forcing an OnCalcFields event...

Hello,
OnCalcFields is called as part of loading records into the TDataset's
cache (all records currently visible on screen are stored in a cache).
Refreshing the cache will therefore recalculate all data. Calling
TDataset.Resync([]) will just do that.
I can not remember whether TDataset.Refresh will do the same thing but I
expect that Refresh only frees the cached field values and not the
caclulated data. So if Refresh doesn't work, you will should call Resync().
Calling Edit/Cancel actually does the same thing.
Regards,
Kees
Jonathan Neve[Microtec] writes:
Quote
Hi,

Does anyone know how to force an OnCalcFields event to get launched? I
need this ability because I have got a calculated field that depends on
data not in the TDataSet (in a TStringList), so I need to recalculate
its value if ever the contents of the TStringList changes.

I usually just call Edit / Cancel, but since the dataset I am working
with right now is read-only, I was wondering if there's another
solution.

Any ideas?

BTW, I am using the BDE in this application.
 

Re:Forcing an OnCalcFields event...

Hi Shane,
Shane Stump writes:
Quote
Jonathan Neve[Microtec] writes:
>Hi,
>
>Does anyone know how to force an OnCalcFields event to get
>launched? I need this ability because I have got a calculated field
>that depends on data not in the TDataSet (in a TStringList), so I
>need to recalculate its value if ever the contents of the
>TStringList changes.
>
>I usually just call Edit / Cancel, but since the dataset I am working
>with right now is read-only, I was wondering if there's another
>solution.
>
>Any ideas?
>
>BTW, I am using the BDE in this application.

How about manually? That is,

if (pDataSet->OnCalcFields != NULL)
{
pDataSet->OnCalcFields(this);
}
No, that won't do because OnCalcFields is normally called when the
DataSet is in a specific mode. If I call it at an arbitrary time of my
own choosing, that is no different than simply setting a value to the
calculated field directly, which, unless I am much mistaken, doesn't
work.
--
Best regards,
Jonathan Neve
_______________
CopyTiger - advanced database replicator for Interbase/Firebird!
Web : www.microtec.fr/copycat/ct
_______________________________________
CopyCat - database replication components for Delphi/C++Builder!
Web : www.microtec.fr/copycat/cc
 

Re:Forcing an OnCalcFields event...

Andrew writes:
Quote
"Jonathan Neve[Microtec]" <XXXX@XXXXX.COM>writes
news:XXXX@XXXXX.COM...
>Hi,
>
>Does anyone know how to force an OnCalcFields event to get
>launched? I need this ability because I have got a calculated field
>that depends on data not in the TDataSet (in a TStringList), so I
>need to recalculate its value if ever the contents of the
>TStringList changes.
>
>I usually just call Edit / Cancel, but since the dataset I am working
>with right now is read-only, I was wondering if there's another
>solution.
>
>Any ideas?
>
>BTW, I am using the BDE in this application.
>--
>Best regards,
>Jonathan Neve
>_______________
>CopyTiger - advanced database replicator for Interbase/Firebird!
>Web : www.microtec.fr/copycat/ct
>_______________________________________
>CopyCat - database replication components for Delphi/C++Builder!
>Web : www.microtec.fr/copycat/cc

Wouldn't calling Dataset.Refresh do the trick?
It might well, though it entails some unnecessary SQL overhead. In the
end, I solved my problem by simply calling :
RefreshQuery(qry);
RefreshQuery is an RX (IIRC) procedure that simply closes the query,
reopens it, and repositions the cursor where it was. This works fine,
but it is overkill. I seem to remember that Refresh isn't implemented in
TQuery (which is what I am using here, TRxQuery to be more precise).
--
Best regards,
Jonathan Neve
_______________
CopyTiger - advanced database replicator for Interbase/Firebird!
Web : www.microtec.fr/copycat/ct
_______________________________________
CopyCat - database replication components for Delphi/C++Builder!
Web : www.microtec.fr/copycat/cc
 

Re:Forcing an OnCalcFields event...

Dmitry Arefiev writes:
Quote
Hello Jonathan

Actually, there are no legal ways to recalculate only fields. I
think, Edit & Cancel will be most cheap one.
Yes, that is what I figured, I was just wondering if perhaps I would missed
something. It would be nice to have an extremely simple method added to
TDataSet, something like "RefreshCalcFields". it is probably not common
to need this, but I must not be the only one.
I agree, Edit & cancel is a good trick, except that it doesn't work
when the dataset is read-only.
--
Best regards,
Jonathan Neve
_______________
CopyTiger - advanced database replicator for Interbase/Firebird!
Web : www.microtec.fr/copycat/ct
_______________________________________
CopyCat - database replication components for Delphi/C++Builder!
Web : www.microtec.fr/copycat/cc
 

Re:Forcing an OnCalcFields event...

Kees Vermeulen writes:
Quote

OnCalcFields is called as part of loading records into the TDataset's
cache (all records currently visible on screen are stored in a
cache). Refreshing the cache will therefore recalculate all data.
Calling TDataset.Resync([]) will just do that.

I can not remember whether TDataset.Refresh will do the same thing but
I expect that Refresh only frees the cached field values and not the
caclulated data. So if Refresh doesn't work, you will should call
Resync().

Calling Edit/Cancel actually does the same thing.
Thanks, I will try Resync next time. I have the impression I had tried
that once before, but I am not sure. Anyway, for now I am simply
refreshing the query, which works fine.
--
Best regards,
Jonathan Neve
_______________
CopyTiger - advanced database replicator for Interbase/Firebird!
Web : www.microtec.fr/copycat/ct
_______________________________________
CopyCat - database replication components for Delphi/C++Builder!
Web : www.microtec.fr/copycat/cc
 

Re:Forcing an OnCalcFields event...

Jonathan Neve[Microtec] writes:
Quote
Hi,

Does anyone know how to force an OnCalcFields event to get launched? I
need this ability because I have got a calculated field that depends on
data not in the TDataSet (in a TStringList), so I need to recalculate
its value if ever the contents of the TStringList changes.

I usually just call Edit / Cancel, but since the dataset I am working
with right now is read-only, I was wondering if there's another
solution.

Any ideas?

BTW, I am using the BDE in this application.
With Pdx tables, I am using that :
type
TTableUnprotected = class(TTable);
procedure RecalcCurrentRecord(Tabe: TTable);
begin
with TTableUnprotected(Table) do begin
GetCalcFields(ActiveBuffer);
DataEvent(deRecordChange, 0); // this force linked controls to
refresh their data
end;
end;
eLion
 

Re:Forcing an OnCalcFields event...

Jonathan Neve[Microtec] writes:
Quote
Hi Shane,

Shane Stump writes:

>Jonathan Neve[Microtec] writes:
>>Hi,
>>
>>Does anyone know how to force an OnCalcFields event to get
>>launched? I need this ability because I have got a calculated field
>>that depends on data not in the TDataSet (in a TStringList), so I
>>need to recalculate its value if ever the contents of the
>>TStringList changes.
>>
>>I usually just call Edit / Cancel, but since the dataset I am working
>>with right now is read-only, I was wondering if there's another
>>solution.
>>
>>Any ideas?
>>
>>BTW, I am using the BDE in this application.
>How about manually? That is,
>
>if (pDataSet->OnCalcFields != NULL)
>{
>pDataSet->OnCalcFields(this);
>}

No, that won't do because OnCalcFields is normally called when the
DataSet is in a specific mode. If I call it at an arbitrary time of my
own choosing, that is no different than simply setting a value to the
calculated field directly, which, unless I am much mistaken, doesn't
work.
I wasn't sure how you were needing it. I have several places where I
call a TkbmMemTable's OnCalcFields manually but I know what the state of
the dataset is in.
Best Regards,
Shane
 

Re:Forcing an OnCalcFields event...

This is what I use on TkbmMemTables when I need to force an OnCalc.
Give if a try and see if it works for you.
type
TDataSetHack = class(TDataSet);
Procedure ForceOnCalcFieldsEvent(ADataSet : TDataSet);
begin
If Not (ADataSet.State in ([dsCalcFields, dsInternalCalc, dsInActive]))
then
TDataSetHack(ADataSet).GetCalcFields(TDataSetHack(ADataSet).CalcBuffer);
end;
Stuart
--