•
•
•
•
What is DaniWeb IT Discussion Community?
You're currently browsing the Pascal and Delphi section within the Software Development category of DaniWeb, a massive community of 391,782 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 3,540 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our Pascal and Delphi advertiser:
Views: 1195 | Replies: 12
![]() |
•
•
Join Date: Mar 2008
Posts: 13
Reputation:
Rep Power: 0
Solved Threads: 0
Well... I could copy the data, and use that, but that would be very slow, and I would have to copy often and a lot. I have a table where records depends on another one. Still, it will be the backup if I can't solve this.
So every time I try to move the active record from inside the OnCalcField event I get a lot of some veird EOleException invalid argument error, even when I don't even read or write any data. I know, I must restore the dataset at the end of the event, as I do every time before EnableControls.
This is my event:
When I try to uncomment the 2 lines it throws the errors, but I can't even catch it. If something handles the error, it couldn't become recursive because qwe prevents it. And I've already tryed with GotoBookmark and First, in case eof would cause this, but it's the same.
Also I can't find anything on google, so it would be nice if somebody could only show me a working example.
Thanks!
So every time I try to move the active record from inside the OnCalcField event I get a lot of some veird EOleException invalid argument error, even when I don't even read or write any data. I know, I must restore the dataset at the end of the event, as I do every time before EnableControls.
This is my event:
delphi Syntax (Toggle Plain Text)
procedure TForm1.calc(DataSet: TDataSet); begin try Dataset.FieldByName('Calc').AsInteger:=10; if qwe then exit; qwe:=true; dataset.DisableControls; //dataset.next; //if not dataset.Eof then dataset.prior; dataset.EnableControls; ListBox1.AddItem(Dataset.FieldByName('SampleNum').AsString,nil); qwe:=false; except showmessage('This never shows!'); ADOQuery1.OnCalcFields:=nil; end; end;
Also I can't find anything on google, so it would be nice if somebody could only show me a working example.
Thanks!
•
•
Join Date: Nov 2007
Posts: 22
Reputation:
Rep Power: 1
Solved Threads: 0
Hi. If you are using ClientDatasets, maybe you can try RecNo and Recordcount to find out if you are in the last record. But from your code I can' t understand why you need it. Maybe that's not exactly your code. Haven't tried my solution, to be honest.
Eduardo
Eduardo
•
•
•
•
Well... I could copy the data, and use that, but that would be very slow, and I would have to copy often and a lot. I have a table where records depends on another one. Still, it will be the backup if I can't solve this.
So every time I try to move the active record from inside the OnCalcField event I get a lot of some veird EOleException invalid argument error, even when I don't even read or write any data. I know, I must restore the dataset at the end of the event, as I do every time before EnableControls.
This is my event:
When I try to uncomment the 2 lines it throws the errors, but I can't even catch it. If something handles the error, it couldn't become recursive because qwe prevents it. And I've already tryed with GotoBookmark and First, in case eof would cause this, but it's the same.delphi Syntax (Toggle Plain Text)
procedure TForm1.calc(DataSet: TDataSet); begin try Dataset.FieldByName('Calc').AsInteger:=10; if qwe then exit; qwe:=true; dataset.DisableControls; //dataset.next; //if not dataset.Eof then dataset.prior; dataset.EnableControls; ListBox1.AddItem(Dataset.FieldByName('SampleNum').AsString,nil); qwe:=false; except showmessage('This never shows!'); ADOQuery1.OnCalcFields:=nil; end; end;
Also I can't find anything on google, so it would be nice if somebody could only show me a working example.
Thanks!
•
•
Join Date: Mar 2008
Posts: 13
Reputation:
Rep Power: 0
Solved Threads: 0
This code obviously doesn't need it, but I will in the program I'm writing. I've just made a test program to separate the error with the minimal code needed to reproduce it.
Of course in the final code there will be some procesing, but I'm happy that I haven't written 100 lines of code in a much more complicated program to debug this stupid error there.
And I've already written that I've tryed bookmark+first to eliminate this, but probably it's not this. Also I've tryed now [icode=delphi]if dataset.recno>dataset.recordcount-3 then exit;[/icode] after the 1st line with the exit, everything is the same. But I don't even reach the end of the dataset, because the dbgrid is too small to draw it (I know this by the logging line), so it really can't be this.
Also a new thing I've noticed that if I make a breakpoint then I see that this code runs for some time without error, and then never runs when the errors come.
Of course in the final code there will be some procesing, but I'm happy that I haven't written 100 lines of code in a much more complicated program to debug this stupid error there.
And I've already written that I've tryed bookmark+first to eliminate this, but probably it's not this. Also I've tryed now [icode=delphi]if dataset.recno>dataset.recordcount-3 then exit;[/icode] after the 1st line with the exit, everything is the same. But I don't even reach the end of the dataset, because the dbgrid is too small to draw it (I know this by the logging line), so it really can't be this.
Also a new thing I've noticed that if I make a breakpoint then I see that this code runs for some time without error, and then never runs when the errors come.
•
•
Join Date: Jun 2006
Location: Blumenau, Brazil
Posts: 67
Reputation:
Rep Power: 3
Solved Threads: 4
•
•
•
•
So every time I try to move the active record from inside the OnCalcField event I get a lot of some veird EOleException invalid argument error, even when I don't even read or write any data.
MoZo1, this event occurs in many circumstances and many times. See this small portion:
OnCalcFields is called frequently, so the code it contains should be brief.
When the AutoCalcFields property is True, OnCalcFields is triggered when:
• A dataset is opened.
• A dataset is put into dsEdit state.
• Focus moves from one visual control to another, or from one column to another is a data-aware grid control and modifications were made to the record.
• A record is retrieved from a database.
So, from the moment that dataset is opened until all data is showed in the DBGrid, your application will notice that OnCalcEvent was triggered a lote of times.
You can have an idea from this by putting one TMemo (Memo1) into your form and adding this code to your OnCalcFields event:
delphi Syntax (Toggle Plain Text)
procedure TForm1.calc(DataSet: TDataSet); begin Memo1.Lines.Add('OnCalcFields passed...'); end;
If You need to make some thing when a DBGrid selection is changed (current record has its position changed), You must use the OnDataChange evento from TDataDouce componente connected to desired dataset.
Bye
"It always has, at least, two ways to make one same thing. Exactly that they are certain and wrong"(Micheus)
Brazil - Blumenau
Brazil - Blumenau
•
•
Join Date: Mar 2008
Posts: 13
Reputation:
Rep Power: 0
Solved Threads: 0
As you can see, I already have a logging code. My event is called every time something read a calculated field. So at the start of the program, when the dbgrid reads whatever it displays, and when I scroll it later, then for only those records.
And I know, that I shouldn't do this, but I'm handling recursive calls, and I'm returning the cursor where it was, so I should be able to do this.
And now the case is that this table has a "foregin key" that points into the same table, so I have to access those records, and I have to make calculated fields from them. To be worse, I have to show the effect when the user changes one value instantly, so this is why I use calculated fields.
Anybody that knows how to fix this, or can link here some webpage about this topic would be appreciated. Thanks!
And I know, that I shouldn't do this, but I'm handling recursive calls, and I'm returning the cursor where it was, so I should be able to do this.
And now the case is that this table has a "foregin key" that points into the same table, so I have to access those records, and I have to make calculated fields from them. To be worse, I have to show the effect when the user changes one value instantly, so this is why I use calculated fields.
Anybody that knows how to fix this, or can link here some webpage about this topic would be appreciated. Thanks!
•
•
Join Date: Jun 2006
Location: Blumenau, Brazil
Posts: 67
Reputation:
Rep Power: 3
Solved Threads: 4
when you must to initilize it.
You can't.
DisableControls only will "stops" to update any data-aware control connected to this dataset. Moving across dataset will trigger this evento in order to update the calculated fields for this new row (cursor position).
In this case, You must use an other dataset only to reach this goal. I sugest that You use some query componente to do this.
Did you understood? If You explain better, putting table fields and relationships, maybe I could examplify.
Bye
•
•
•
•
... but I'm handling recursive calls, and I'm returning the cursor where it was, so I should be able to do this.
DisableControls only will "stops" to update any data-aware control connected to this dataset. Moving across dataset will trigger this evento in order to update the calculated fields for this new row (cursor position).
•
•
•
•
And now the case is that this table has a "foregin key" that points into the same table, so I have to access those records, and I have to make calculated fields from them. To be worse, I have to show the effect when the user changes one value instantly, so this is why I use calculated fields.
Did you understood? If You explain better, putting table fields and relationships, maybe I could examplify.
Bye
"It always has, at least, two ways to make one same thing. Exactly that they are certain and wrong"(Micheus)
Brazil - Blumenau
Brazil - Blumenau
•
•
Join Date: Mar 2008
Posts: 13
Reputation:
Rep Power: 0
Solved Threads: 0
I must initialize it every time something reads it, because delphi doesn't store them, and TADOQuery can't use internally calculated fields. But this doesn't really matter, because if it can run once, it could run any times.
•
•
•
•
You can't.
DisableControls only will "stops" to update any data-aware control connected to this dataset. Moving across dataset will trigger this evento in order to update the calculated fields for this new row (cursor position).
So with other words, only outside calls will need that data, but when the data is being calculated, the object (that will use this database) will turn off the calculation internally, because every call that occurs there are from inside (of course, because delphi is strictly single threaded), so it won't use that data ever, so other calculation requests won't cause recursions, but instantly returns with nothing instead.
•
•
•
•
In this case, You must use an other dataset only to reach this goal. I sugest that You use some query componente to do this.
And refresh it with all of the records every time the other one get changed. If it can't be helped, I'll do this of course, but I still don't know what is this exeption, and why is it there.
•
•
•
•
Did you understood? If You explain better, putting table fields and relationships, maybe I could examplify.
Bye
I know what I'm doing. I don't know what the hell Delphi is doing. T_T
Of course I could solve this with the second table, or a memory cache, or whatever easily, but this sollution would be the easyest and fastest, and I don't see any obstacle in theory why I can't do this. Well, at least I've tryed... Thanks for the help anyway!
•
•
Join Date: Aug 2007
Location: Gunnison, Colorado
Posts: 54
Reputation:
Rep Power: 2
Solved Threads: 1
I haven't tried to run your code, but I can tell you this:
When your uncomment the line which moves to the next record, what is happening is that Delphi is calling OnCalc again automatically as soon as the record changes, and you are probably trashing the stack when the call goes into an endless loop because each call to OnCalc moves the record which send it back to OnCalc.......... OnCalc is best used to just update the current record (or other data dependent on the current record). It is a very useful tool (I sure with C#.NET had it) but it can't be used for everything.
I'm not quite sure what it is you're actually trying to accomplish but it looks like you are using the wrong event.
When your uncomment the line which moves to the next record, what is happening is that Delphi is calling OnCalc again automatically as soon as the record changes, and you are probably trashing the stack when the call goes into an endless loop because each call to OnCalc moves the record which send it back to OnCalc.......... OnCalc is best used to just update the current record (or other data dependent on the current record). It is a very useful tool (I sure with C#.NET had it) but it can't be used for everything.
I'm not quite sure what it is you're actually trying to accomplish but it looks like you are using the wrong event.
•
•
Join Date: Mar 2008
Posts: 13
Reputation:
Rep Power: 0
Solved Threads: 0
Well, I'm going to forfeit this one, but please notice these:
-> No recursion occurs on my level of code. And I've already told that the error is an EOleException and not a stack overflow.
And again this one too: Watch qwe! When my event is triggered, then it sets the qwe variable (disabling itself), then disablecontrols, and after then it moves the dataset, retriggers itself, but won't do anything while qwe is true, because it knows that calculating isn't needed, and when it've finished with the processing, it unsets qwe (enabling itself), enablecontrols and returns the value. The visual controls won't notice a thing because of disablecontrols, and the recursive calling on the dataset is handled.
And at last, no stack overflow error, no damn long stack, and no recursion can be detected through breakpoints. Probably if you haven't tryed my code, you will think, this isn't something strange, and I've just failed to notice a stack overflow, and writing stupidity here. But even then, you should be able to point out what's wrong with my handling.
And if you're interested, I use delphi 2005!
•
•
•
•
Also a new thing I've noticed that if I make a breakpoint then I see that this code runs for some time without error, and then never runs when the errors come.
And again this one too: Watch qwe! When my event is triggered, then it sets the qwe variable (disabling itself), then disablecontrols, and after then it moves the dataset, retriggers itself, but won't do anything while qwe is true, because it knows that calculating isn't needed, and when it've finished with the processing, it unsets qwe (enabling itself), enablecontrols and returns the value. The visual controls won't notice a thing because of disablecontrols, and the recursive calling on the dataset is handled.
And at last, no stack overflow error, no damn long stack, and no recursion can be detected through breakpoints. Probably if you haven't tryed my code, you will think, this isn't something strange, and I've just failed to notice a stack overflow, and writing stupidity here. But even then, you should be able to point out what's wrong with my handling.
And if you're interested, I use delphi 2005!
Last edited by MoZo1 : May 12th, 2008 at 2:20 am.
•
•
Join Date: Jun 2006
Location: Blumenau, Brazil
Posts: 67
Reputation:
Rep Power: 3
Solved Threads: 4
•
•
•
•
And refresh it with all of the records every time the other one get changed.
•
•
•
•
And again this one too: Watch qwe! When my event is triggered, then it sets the qwe variable (disabling itself), then disablecontrols, and after then it moves the dataset, retriggers itself, but won't do anything while qwe is true, because it knows that calculating isn't needed, and when it've finished with the processing, it unsets qwe (enabling itself), enablecontrols and returns the value. The visual controls won't notice a thing because of disablecontrols, and the recursive calling on the dataset is handled.
Just make this change in your code:
delphi Syntax (Toggle Plain Text)
... Dataset.FieldByName('Calc').AsInteger:=10; if qwe then begin ListBox1.AddItem('OnCalcField event recalled',nil); exit; end; qwe:=true; ...
•
•
•
•
And at last, no stack overflow error, no damn long stack, and no recursion can be detected through breakpoints.
Is very difficult to debug this kind of code, because a break point at this event will unfortunately make the DBGrid paint its self. And in order to get data to display...
Take a look at the attached image. I have positioned the delphi windows in order to prevente redrawing influence.
The DBGrid's linked dataset has seven records where PersonCode has a sequencial value from 1 to 7. Notice this points:
- Call Stack window shows what is in process where the error occurs;
- Editor windows shows the break point at line where the error occurs - DBGrid unit. See tooltip window appoints the EOleException;
- At background, Form1 is the program running. Looking at the DBGrid we can ask: Where is displayed values when PersonCode is 2? And looking to ListBox we see that a recursive call was made when trying process this value.
You can try by your self.
•
•
•
•
I know what I'm doing. I don't know what the hell Delphi is doing. T_T
..., and I don't see any obstacle in theory why I can't do this.
My final words is: Do not use OnCalcFields event by this way.
Good luck.
"It always has, at least, two ways to make one same thing. Exactly that they are certain and wrong"(Micheus)
Brazil - Blumenau
Brazil - Blumenau
![]() |
•
•
•
•
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
•
•
•
•
•
•
•
•
DaniWeb Pascal and Delphi Marketplace
Other Threads in the Pascal and Delphi Forum
- Previous Thread: using method or dereferenced object pointer
- Next Thread: txt files in pascal


Linear Mode