Access中的自定义错误消息

来自  https://blog.csdn.net/cxygs5788/article/details/106352428

首先,我不是VBA编码方面的技术专家。我从出色的Access / VBA论坛中学到了大部分知识,bytes.com (原thescripts.com )。恩,我将为与我的技术知识处于同一水平或更低水平的人员撰写这篇文章。我会用外行的话,或者说我自己的话来理解,希望您能像我一样理解它。

错误类型

我们需要了解,MS-Access中存在不同类型的错误,并且我并不完全了解这些错误的真正技术名称,但是根据我的经验,在大多数情况下,我只会遇到两种错误,始终捕获并为其生成客户错误消息。我想将这些错误称为1)表单错误,2)子过程错误 。

表格错误

        我将其称为“表单错误”,因为这些错误通常在表单验证期间发生。 意味着,没有实际的子过程或VBA代码执行来触发错误。由窗体或控件失去焦点,或窗体或控件被更新触发此错误。有很多可能的原因,但仅举几例,以下是常见的示例。

*设置为索引(无重复)的字段,但是提供了重复值。

*该字段设置为必填,但尚未为该字段输入任何数据

*该字段已使用输入掩码设置,但输入的数据不符合输入掩码要求

还有其他示例,但是这些是我通常陷阱错误的最常见示例。由于没有单击特定的按钮,也没有要求触发错误的过程,因此,此错误归类为“表单错误”。在大多数情况下,这可以通过移至下一条或新记录或将焦点从主窗体移至其子窗体来触发。这两个操作都会导致记录的更新或保存,因此,如果存在验证要求,则会触发此类错误。

子程序错误

       我将其称为“子过程错误”,因为我所做的大多数项目都是这样,这些错误是由在vba中执行代码触发的,无论我自己编写代码还是使用向导为我创建代码。 这就是为什么我也称此按钮错误的原因,因为在大多数情况下(不是全部),我将子过程vba代码放在按钮的On Click事件上。这些错误几乎是由与上述“表单错误”相同的验证原因完全触发的,只是并不一定要通过离开表单或移动到另一个或新的记录或将焦点从表单更新记录。主表单到子表单。举例来说,我已将field属性设置为Required。 如果我没有在该字段中放入任何数据,则保存记录时会触发验证错误。 在这种情况下,如果我移动到其他记录,那么就是该记录被更新或保存的时间,那么将从上方触发Form Errors。但是,如果我希望用户单击“保存”按钮,该按钮应实际检查或验证数据输入?在此示例中,如果我保留必填字段中没有数据,则单击“保存”按钮,则不会触发“表单错误”,而是触发了子过程我在“保存”按钮的“单击时”事件上编码的错误。 因此,如果我不单击该按钮(则不会调用子过程),则不会触发该错误,因为不会进行数据验证。 除非我关闭表单,或者可以使用菜单栏保存它,或者使用导航按钮或鼠标滚动移动到下一条记录,否则不会这样做-这将触发表单错误,而不是子过程错误(按钮错误)。

如何捕捉错误

由于在本文中,我引用了两种类型的错误,因此您应该已经知道捕获此错误的方式有所不同。方法相似,但是放置位置和标识方式不同。要捕获表格错误,可以使用表格的错误事件。要捕获子过程错误,您需要将该错误处理程序放在子过程级别。

使用DataErr变量捕获Form Error 。使用Err.Number常量和属性捕获子过程错误 。

我捕获错误的方法是使用MsgBox告诉我错误号是什么,确定错误编号后,我可以使用If..Then..ElseSelect Case语句来自定义客户错误消息

取决于触发的错误号。

** 捕捉表格错误

在窗体的“发生错误”事件上,输入以下代码。

Private Sub frmMyForm_Error (DataErr as Integer, Response as Integer)

     MsgBox   "Error No.:" &   DataErr

End Sub

MsgBox将告诉您错误号,然后在该消息框上单击“确定”,然后将显示“默认错误消息”。

现在,在表单上进行尝试输入并触发错误。 在此示例中,我将有意保留“必填”字段为空,然后继续进行新记录。 错误将被触发,我将收到带有以下消息的消息框:

'错误编号:3314' 。

我单击确定,然后将看到默认的MS Access错误消息:

“ 字段MyField不能包含Null值,因为此字段的Required属性设置为True。在此字段中输入一个值。”

并不是我知道错误编号和错误描述,然后将其捕获并分配给客户错误消息。

为此,我将使用此代码。

Private Sub frmMyForm_Error (DataErr as Integer, Response as Integer)

If DataErr = 3314 Then

    MsgBox "MyField is required.  Please enter a data in this field."

Else

    MsgBox "Error No.:" & DataErr

End Sub

现在,我将再次尝试。 这次,当我移动到新记录时,将需要查询的字段留空时,我会看到一条错误消息:

'要求MyField。 请在此字段中输入数据。” 这是我的自定义错误消息。

在单击“确定”后,默认的访问错误消息再次出现。 现在有问题了! 我不希望用户再看到此信息,只希望他们看到我的自定义错误消息。 因此,我需要禁止该默认错误消息。 为此,我将在自定义错误消息之后立即使用Response变量和常量acDataErrContinue。

Private Sub frmMyForm_Error (DataErr as Integer, Response as Integer)

If DataErr = 3314 Then

    MsgBox "MyField is required.  Please enter a data in this field."

    Response = acDataErrContinue

Else

    MsgBox "Error No.:" & DataErr

End If

End Sub

Response = acDataErrContinue只是告诉访问权限不再显示默认错误消息。

如果触发的错误不是3314,则我将看到错误编号和默认错误消息。

因此,现在实际上取决于您的情况是,您认为可以触发多少个错误,需要使用自定义错误消息进行分配。

如果您问我,我发现这些错误是我的项目中触发的最常见错误:

2107:The value you entered doesn't meet the validation rule defined for the field or control.To see the validation rule, click Design view, click the appropriate field,and then, if the property sheet isn't open, click the Properties button on the toolbar.Then click the Data tab.To solve this problem, enter a value that meets validation rule, or press ESC to undo your changes 

2113:The value you entered isn't valid for this field.For example, you may have entered text in a numeric field or a number that is larger than the FieldSize setting permits. 

2169:You can't save this record at this time.Microsoft Access may have encountered an error while trying to save a record.If you close this object now, the data changes you made will be lost.Do you want to close the database object anyway? 

2237 : (can be replaced by the On Not In List event of a combobox/listbox) The text you entered isn't an item in the list.Select an item from the list, or enter text that matches one of the listed items. 

3022:The changes you requested to the table were not successful because they would create duplicate values in the index, primary key, or relationship. Change the data in the field or fields that contain duplicate data, remove the index, or redefine the index to permit duplicate values and try again. 

3200:The record cannot be deleted or changed because table includes related records. 

3201:You can't add or change a record because a related record is required in table

3314:The field can't contain a Null value because the Required property for this field is set to True. Enter a value in this field. 

3315:Field can't be a zero-lenght string

3316:

3317:One or more values are prohibited by the validation rule set for . Enter a value that the expression for this field can accept.

由于我想确保在任何情况下都会触发这些错误,因此数据库将显示我的自定义错误消息,然后在Form_Error Event中使用Select Case语句。

Private Sub Form_Error (DataErr as Integer, Response as Integer)

Select Case DataErr

    Case 2107

        MsgBox "This is my custom error message for Error No 2107"

    Case 2113

        MsgBox "This is my custom error message for Error No 2113"

    Case 2169

        MsgBox "This is my custom error message for Error No 2169"

    Case 2237

        MsgBox "This is my custom error message for Error No 2237"

    Case 3022

        MsgBox "This is my custom error message for Error No 3022"

    Case 3200

        MsgBox "This is my custom error message for Error No 3200"

    Case 3201

        MsgBox "This is my customer error message for Error No 3201"

    Case 3314

        MsgBox "This is my customer error message for Error No 3314"

    Case 3315

        MsgBox "This is my customer error message for Error No 3315"

    Case 3316

        MsgBox "This is my customer error message for Error No 3316"

    Case 3317

        MsgBox "This is my customer error message for Error No 3317"   

    Case Else

        MsgBox "This is an unexpected error.  Please report this to the administrator."

End Select

Response = acDataErrContinue

End Sub

在全球范围内处理表格错误

我不确定我是否在全球范围内使用了正确的术语,但是我的意思是我想确保所有形式的所有错误均由我的cutsomer错误消息处理。一种方法是将thist错误代码复制并粘贴到表单的每个On Error事件中。问题是我的VBA代码出现在每个表单模块中的方式非常特别,我不喜欢在每个表单模块中一遍又一遍地看到相同的代码。 我希望表单模块尽可能整洁,因此冒险尝试学习标准模块。在...的帮助下FishVal ,我终于学会了。我想要的是只键入一次此客户错误消息,然后从表单的每个模块中调用它。所以我将创建一个新模块并将其命名MyCodes 。然后,我编写具有此自定义错误处理的公共过程,以便可以从项目中的任何形式调用它。 依此类推MyCodes模块,我有这个Sub过程。

Public Sub FErrorHandler (ByVal DataErr as Integer)

Select Case DataErr

    Case 2107

        MsgBox "This is my custom error message for Error No 2107"

    Case 2113

        MsgBox "This is my custom error message for Error No 2113"

    Case 2169

        MsgBox "This is my custom error message for Error No 2169"

    Case 2237

        MsgBox "This is my custom error message for Error No 2237"

    Case 3022

        MsgBox "This is my custom error message for Error No 3022"

    Case 3200

        MsgBox "This is my custom error message for Error No 3200"

    Case 3201

        MsgBox "This is my customer error message for Error No 3201"

    Case 3314

        MsgBox "This is my customer error message for Error No 3314"

    Case 3315

        MsgBox "This is my customer error message for Error No 3315"

    Case 3316

        MsgBox "This is my customer error message for Error No 3316"

    Case 3317

        MsgBox "This is my customer error message for Error No 3317"   

    Case Else

        MsgBox "This is an unexpected error.  Please report this to the administrator."

End Select

End Sub

此后,我仍然需要编写每个表单的On Error事件的代码。 要从我的表单中调用它,请使用以下代码:

Private Sub Form_Error (DataErr as Integer, Response as Integer) MyCodes .FErrorHanlder (DataErr)

      Response = acDataErrConitnue

End Sub

是! 我仍然需要在每个表单模块上执行此操作,但是这样做会更好。 首先,因为它看起来更整洁,更重要,所以如果我要更改错误消息,或者可能添加新的DataErr , 则只需要在MyCodes模块中编辑Public Procedure , 不是在每个表单上都可以进行编辑在我的项目中。 

** 捕获子程序错误

对我来说,捕获这些错误的唯一方法是我通常要调用“按钮错误”,方法是使用子级别

错误属性。

在此示例中,我有一个名为cmdSave的命令按钮,用于保存记录并验证数据,并告诉用户验证是否成功。

编码应如下所示:

Private Sub cmdSave_Click()

      DoCmd.RunCommand acCmdSaveRecord

MsgBox "Changes saved successfully."

但是,如果我错过了任何必填字段,或者可能触发了其他错误,那么我的Form Error处理程序将不会处理它。

因此,我需要告诉VBA,如果遇到错误,则需要自定义错误消息。

正如我之前提到的,关于子过程错误,我们使用Err.Number而不是DataErr来捕获过程级别错误:

Private Sub cmdSave_Click()

On Error GoTo ErrorHandler

DoCmd.RunCommand acCmdSaveRecord

MsgBox "Changes saved successfully."

ExitErrorHandler:

Exit Sub

ErrorHandler:

    MsgBox "Error No.:" & Err.Number

    Resume ExitErrorHanlder

End If

现在,我将需要的字段再次留空,这一次,我将单击“保存”按钮,而不是移至新记录。 然后,我看到消息“错误号:3314 ”,然后是默认访问错误消息。

对于客户错误消息,我将使用

如果..Then..ElseSelect Case语句,则acDataErrContinue常量

禁止显示默认错误消息。

我将直接转到“选择案例”示例,因为我希望在单击按钮时处理所有可能的错误。

所以我的编码是这样的:

Private Sub cmdSave_Click()

On Error GoTo ErrorHandler

DoCmd.RunCommand acCmdSaveRecord

MsgBox "Changes saved successfully."

ExitErrorHandler:

Exit Sub

ErrorHandler:

Select Case Err.Number

    Case 2107

        MsgBox "This is my custom error message for Error No 2107"

    Case 2113

        MsgBox "This is my custom error message for Error No 2113"

    Case 2169

        MsgBox "This is my custom error message for Error No 2169"

    Case 2237

        MsgBox "This is my custom error message for Error No 2237"

    Case 3022

        MsgBox "This is my custom error message for Error No 3022"

    Case 3200

        MsgBox "This is my custom error message for Error No 3200"

    Case 3201

        MsgBox "This is my customer error message for Error No 3201"

    Case 3314

        MsgBox "This is my customer error message for Error No 3314"

    Case 3315

        MsgBox "This is my customer error message for Error No 3315"

    Case 3316

        MsgBox "This is my customer error message for Error No 3316"

    Case 3317

        MsgBox "This is my customer error message for Error No 3317"   

    Case Else

        MsgBox "This is an unexpected error.  Please report this to the administrator."

End Select

Response = acDataErrContinue

Resume ExitErrorHanlder

End If

在全球范围内处理子程序错误

现在,我不必担心我的错误。 我现在处理的唯一问题是,我再次希望代码尽可能整洁。

更重要的是,我喜欢20个具有保存按钮的表单,它们执行相同的命令,并且我不想将冗长的代码复制粘贴到每个表单中。

所以我回到我的模块MyCodes并创建另一个公共过程。

Public Sub PErrorHandler()

Select Case Err.Number

    Case 2107

        MsgBox "This is my custom error message for Error No 2107"

    Case 2113

        MsgBox "This is my custom error message for Error No 2113"

    Case 2169

        MsgBox "This is my custom error message for Error No 2169"

    Case 2237

        MsgBox "This is my custom error message for Error No 2237"

    Case 3022

        MsgBox "This is my custom error message for Error No 3022"

    Case 3200

        MsgBox "This is my custom error message for Error No 3200"

    Case 3201

        MsgBox "This is my customer error message for Error No 3201"

    Case 3314

        MsgBox "This is my customer error message for Error No 3314"

    Case 3315

        MsgBox "This is my customer error message for Error No 3315"

    Case 3316

        MsgBox "This is my customer error message for Error No 3316"

    Case 3317

        MsgBox "This is my customer error message for Error No 3317"   

    Case Else

        MsgBox "This is an unexpected error.  Please report this to the administrator."

End Select

End Sub

如果可以看到,与Form Error的“(DataErr as Integer)”相比,我不必声明变量

现在,我需要从表单的每个“保存”按钮错误处理程序中调用以下过程:

Private Sub cmdSave_Click()

On Error GoTo ErrorHandler

DoCmd.RunCommand acCmdSaveRecord

MsgBox "Changes saved successfully."

ExitErrorHandler:

Exit Sub

ErrorHandler:

MyCodes.PErrorHandler

Response = acDataErrContinue

Resume ExitErrorHanlder

End If

现在,如果需要编辑或添加自定义错误消息,则只需在MyCodes模块中对其进行编辑,它将应用于所有表单的所有保存按钮。

你可能感兴趣的:(Access中的自定义错误消息)