我已经实现了一个可编辑的 DBGrid。如果未正确填写字段,则会引发异常并显示消息,例如:
'08:00::00' is not a valid time
如何捕获这些异常,以便显示我编写的消息而不是自动生成的消息?如果有任何帮助,我将不胜感激。
正如@teran 在他的评论中指出的那样,异常是由TDataSet
绑定到 的(或其组件之一)TDBGrid
或数据库引擎本身引发的。
您可以尝试处理TDataSet.OnPostError
(另见OnUpdateError
和OnEditError
):
TDataSet.OnPostError:当应用程序尝试修改或插入记录并引发异常时发生。编写一个 OnPostError 事件处理程序来处理尝试发布记录失败时发生的异常。
请注意,您始终可以使用Application.OnException
全局事件处理程序来捕获应用程序中的任何 EDBxxx 异常。
编辑:在任何实际数据修改或字段的任何 Post 操作之前EConvertError
引发异常,即: TDateTimeField
0045af91 +085 Project1.exe SysUtils StrToDateTime <- EConvertError
004ab76a +042 Project1.exe Db TDateTimeField.SetAsString
004a9827 +007 Project1.exe Db TField.SetText
004a95d9 +029 Project1.exe Db TField.SetEditText
004d6448 +014 Project1.exe DBGrids TCustomDBGrid.UpdateData
004d087f +02b Project1.exe DBGrids TGridDataLink.UpdateData
004d599a +01a Project1.exe DBGrids TCustomDBGrid.MoveCol
StrToDateTime
在里面抛出异常TDateTimeField.SetAsString
,不接触数据,TDataSet.OnxxxError
事件处理程序根本不会被触发。
所以你的选择是(在发布模式下测试应用程序):
EConvertError
1.通过拦截和处理Application.OnException
。
2.TField.EditMask
用于将用户输入限制为有效的时间格式,例如!90:00;1;_
,或在您的 Grid 中使用就地DateTimePicker 编辑器。(并避免捕获此异常)。
3.Override TDateTimeField
:使用持久字段TDataSet
并创建一个 inter-poser 类,如下所示:
type
TDateTimeField = class(Db.TDateTimeField)
protected
procedure SetAsString(const Value: string); override;
end;
TForm1 = class(TForm)
...
procedure TDateTimeField.SetAsString(const Value: string);
begin
try
inherited SetAsString(Value);
except
on E: EConvertError do
begin
ShowMessage(E.Message);
Abort;
end;
end;
end;
如果引发异常,则在调试器中运行时应该显示两条错误消息。其中一个将被调试器捕获,第二个由 UI 处理(当以用户身份运行程序时,您只会看到第二个)。
异常错误消息应该包含一个字符串,如
Appname.exe 引发异常 EExceptionName 并带有消息 XXX
您需要注意 EExceptionName。
围绕创建异常的代码块,您需要编写
...
try
code that can cause the exception here
except
on e: EExceptionName do
begin
ShowMessage('Your apps nicer error message here');
end;
end;
注意 - 如果您不拨打退出电话;处理异常后,您的代码将在您的 try..except 块之后继续执行所有内容。此外,如果在同一个代码块中有很多事情会导致相同的错误消息,那么您可能无法编写任何过于具体的内容。e.Message 是一个字符串,它保存在未处理的异常中显示的消息,并且可能对呈现给用户也很有用。
还要尝试远离 BDE - 现代系统对 ADO 的支持要好得多。