'cursor is in BOF position' error

205 Views Asked by At

On before delete of the table I have :

procedure TData_Module.MyTableBeforeDelete(DataSet: TDataSet);
begin    
if MessageDlg('Are you sure you want to delete the record written by '+
                  QuotedStr(MyTable.FieldByName('written_by_who').AsString),mtConfirmation,[mbYes,mbNo],0) = mrYes then
    MyTable.Delete;
end;

However, on trying I get the error : ...cursor is in BOF position

What goes ? Database is Accuracer.

edit : The entire code above :)

2

There are 2 best solutions below

0
On BEST ANSWER

As I said in comments, it sounded from your q as if you are calling Delete within the dataset's BeforeDelete event. Don't do that, because the BeforeDelete event occurs while the dataset is already in the process of deleting the record. So you deleting it is pulling the rug out from under the dataset's built-in code.

So, if you want the user's confirmation, get it before calling Delete, not inside the BeforeDelete event. Btw, the standard TDBNavigator has a ConfirmDelete property associated with its integrated DeleteRecord button which will do exactly that, i.e. pop up a confirmation prompt to the user.

More generally, people frequently create problems for themselves by trying to perform actions within a dataset event which are inappropriate to the state the dataset is in when the event code is called. The TDataSet has a very carefully designed flow of logic to its operations, and t is rather too easy for the inexperienced on unwary programmer to subvert its logic by doing something in a TDataSet event that shouldn't be there: One example is calling Delete inside an event. Another, frequently encountered ,one is executing code which moves the dataset's cursor inside an event that's called as result of moving the cursor, like the AfterScroll event, f.i.

There's no easy rule to say what you should and shouldn't do inside a dataset event, but generally speaking, any action you take which attempts to change the dataset's State property (see TDataSetState in the OLH) should be your prime suspect when you find that something unexpected is happening.

I suppose another general rule, with exceptions that are usually clear from the descriptions of events in the OLH, is that dataset events should generally be used for reacting to the event by doing something to some other object, like updating a status panel, rather than doing something to the dataset. F.i. the AfterScroll event is very useful for reacting to changes when the dataset's cursor is moved. The exceptions are events like BeforePost which are intended to allow you the opportunity to do things (like validate changes to the dataset's fields).

Btw, you can call Abort from inside the BeforeDelete event and it will prevent the deletion. However, imo, it's cleaner and tidier to check whether a deletion should go ahead and plan and code for its consequences before going ahead rather than have to back out part way through. So, with respect, I disagree with the other answer. The time to decide whether to cross a bridge is before you start, not when you're already part way across it. Ymmv, of course.

4
On

The question is in the right place. To ask before the delete is wrong because it forces you to ask the question every time you call Delete. A more correct answer is to abort the delete here, in the OnBeforeDelete, if the user doesn't want to delete.