【问题标题】:Exceptions on DBGrid editingDBGrid 编辑的例外情况
【发布时间】:2012-10-11 09:15:54
【问题描述】:

我已经实现了一个可编辑的 DBGrid。如果某个字段未正确填写,则会引发异常并显示一条消息,例如:

'08:00::00' is not a valid time

如何捕获这些异常,以便显示我编写的消息而不是自动生成的消息?如有任何帮助,我将不胜感激。

【问题讨论】:

  • 最好也提供你已经开发的代码
  • 这不是DBGrid 异常。它是由DataSet 组件在Post() 方法中抛出的。您使用哪些 DataSet 组件,ADO、BDE 还是其他?
  • 我正在使用 BDE。 DataSet 组件的类型是 TQuery。

标签: delphi delphi-5


【解决方案1】:

正如@teran 在他的评论中指出的那样,异常是由绑定到TDBGridTDataSet(或其组件之一)或由数据库引擎本身引发的。

你可以尝试处理TDataSet.OnPostError(另见OnUpdateErrorOnEditError):

TDataSet.OnPostError: 当应用程序尝试修改或插入记录时发生,并且 引发异常。编写一个 OnPostError 事件处理程序来处理 尝试发布记录失败时发生的异常。

请注意,您始终可以使用 Application.OnException 全局事件处理程序来捕获应用程序中的任何 EDBxxx 异常。


编辑:EConvertError 异常在 任何实际数据修改之前引发,或 TDateTimeField 字段的任何 Post 操作,即:

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

StrToDateTimeTDateTimeField.SetAsString 内抛出异常,不接触数据,并且 TDataSet.OnxxxError 事件处理程序根本不会被触发。

所以你的选择是(在发布模式下测试应用程序):

1.通过Application.OnException拦截并处理EConvertError
2.使用TField.EditMask 将用户输入限制为有效的时间格式,例如!90:00;1;_ 或就地使用 DateTimePicker editor inside your Grid。 (并避免捕获此异常)。
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;

【讨论】:

  • 感谢您的回答。我尝试了这个解决方案(OnUpdateError 事件处理程序),它可以正常处理数据库错误,但我该如何处理转换错误?例如,当我填写 DBGrid 中的 starthour 字段并按 Tab 键转到下一个字段时,我收到消息:Project Text.exe 引发异常类 EConvertError,消息为 ''7::' is not a valid time'。跨度>
  • 非常感谢您的详细解释!我选择了第三种解决方案。
【解决方案2】:

如果引发异常,则在调试器中运行时应显示两条错误消息。其中一个将被调试器捕获,第二个由 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 的支持要好得多。

【讨论】:

  • 在我看来 OP 根本不使用任何代码(DataSourceAutoEdit 模式下),因为他不知道代码异常在哪里抛出
  • 在这种情况下用try inherited post; except on e: EExceptionName do覆盖数据集的Post方法
  • 我包围了这段代码'Query2.ApplyUpdates;'在尝试...除了块,但效果不是我想要的。在调试模式下,显示旧的两条消息,然后还显示第三条消息(我在 except 子句中的自定义消息)。我只想显示我的消息。
  • @Rick77 调试正常。在发布模式下,您只会看到一条消息(在 except 中是您的),试试吧。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-25
  • 1970-01-01
  • 1970-01-01
  • 2019-08-14
  • 2011-12-25
  • 2010-09-15
相关资源
最近更新 更多