
| Subject: | Not the old BOF or EOF is true problem |
| Posted by: | Michael Verhagen |
| Date: | Sun, 30 Aug 2009 |
I've read many messages over the years about the "Either BOF or EOF is true" problem, but all of the proposed solutions deal with people who have Delphi 5 with ADOExpress components but have failed to upgrade to the service pack for those components that fixed the problem for most cases. But even when I was using Delphi 5, I knew that the symptoms I was seeing were NOT caused by obsolete ADOExpress components because I had updated my stuff long before I had the problem.
As if any additional evidence was needed to show that the problem I'm seeing has nothing to do with the problems in ADOExpress components in Delphi 5, I now see the problem in a new Delphi 2007 app that received no code from earlier apps, and it seems easily reproducible.
The symptoms are these:
1) Add a record.
2) Add a second record.
3) Delete either of those records
4) Delete the other of those two records, resulting in an empty table.
5) No problem.
OR
1) Add a record.
2) Move to some other record, by navigating in the parent's table.
3) Return to the just-added record by navigating back to the parent of the added record.
4) Delete the just-added record
5) No problem.
OR
1) Add a record
2) Delete that record.
3) See the "Either BOF or EOF is true" message, but the DBgrid that displays the record still shows the delete record, but navigating away and back on the parent's record causes the grid to correctly display that indeed the record was deleted. This behavior is unchanged even if the DBGrid is disconnected from the ADODataSet.
I've seen this problem in various situations over the years, and when it copped up, I just used an ADOCommand component to issue DELETE in SQL instead of using DataSet.Delete. This seemed to be a work-around. I haven't tried that approach in this situation, but I'd rather figure out what's really going on and fix it correctly. That's because there is another piece of code that could be contributing to the problem, and I don't want the SQL method to mask something else I'm doing wrong.
In the DataSet's AfterPost handler, I bounce (close/open) the DataSet because its SQL contains sub-SELECT statements that look-up names from id values, and unless I do that, the DBGrid leaves the name columns blank though the other fields from the added record appear there. Use of Refresh does not accomplish this.
var nSaveID: Integer;
begin
nSaveID := DataSet.FieldByName('id').AsInteger;
DataSet.DisableControls;
DataSet.Close;
DataSet.Open; // to display looked-up name
DataSet.Locate('id', nSaveID, []);
DataSet.EnableControls;
end;
If I remove that AfterPost bounce of the DataSet, the BOF/EOF problem disappears, but I also don't get the name in the table.
Can you suggest another way to get the name to be displayed in the DBGrid that doesn't involve bouncing the table, or a way to bounce the table but not get the BOF/EOF message?