-1

在删除表之前,我有:

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;

但是,在尝试时出现错误: ...光标处于 BOF 位置

怎么回事?数据库是Accuracer。

编辑:上面的整个代码:)

4

2 回答 2

3

正如我在评论中所说,从您的 q 听起来好像您在数据集的 BeforeDelete 事件中调用 Delete 。不要那样做,因为 BeforeDelete 事件发生在数据集已经在删除记录的过程中。所以你删除它就是从数据集的内置代码中拉出地毯。

因此,如果您想要用户的确认,请在调用 Delete 之前获取它,而不是在 BeforeDelete 事件中。顺便说一句,标准的 TDBNavigator 具有与其集成的 DeleteRecord 按钮相关联的 ConfirmDelete 属性,该按钮将执行此操作,即向用户弹出确认提示。

更一般地,人们经常通过尝试在数据集事件中执行不适合调用事件代码时数据集所处状态的操作来为自己制造问题。TDataSet 对其操作有一个非常精心设计的逻辑流,对于缺乏经验的粗心程序员来说,通过在 TDataSet 事件中做一些不应该存在的事情来破坏它的逻辑太容易了:一个例子是在内部调用 Delete一个事件。另一种经常遇到的情况是执行代码,将数据集的光标移动到一个事件中,该事件被称为移动光标的结果,例如 AfterScroll 事件,fi

没有简单的规则来说明在数据集事件中应该做什么和不应该做什么,但一般来说,当您发现任何试图更改数据集的 State 属性的操作(请参阅 OLH 中的 TDataSetState)时,应该是您的主要嫌疑人意料之外的事情正在发生。

我想另一个一般规则,除了通常从 OLH 中的事件描述中清楚的例外情况外,数据集事件通常应该用于通过对其他对象执行某些操作来对事件做出反应,例如更新状态面板,而不是数据集做某事。Fi AfterScroll 事件对于在数据集的光标移动时对更改做出反应非常有用。例外情况是像 BeforePost 这样的事件,它们旨在让您有机会做一些事情(例如验证对数据集字段的更改)。

顺便说一句,您可以从 BeforeDelete 事件中调用 Abort ,它将阻止删除。但是,imo,检查是否应该继续删除并在继续之前对其后果进行计划和编码,而不是必须中途退出,这样会更干净、更整洁。所以,恕我直言,我不同意另一个答案。决定是否过桥的时间是在你开始之前,而不是在你已经过桥的时候。嗯,当然。

于 2015-08-20T17:41:33.363 回答
0

问题是在正确的地方。在删除之前询问是错误的,因为它会迫使您每次调用Delete时都询问问题。如果用户不想删除,更正确的答案是在OnBeforeDelete中中止删除。

于 2015-08-20T21:41:37.743 回答