我在MS Access中使用form_error事件来捕获错误,这只会给出dataerr integer
而不是像vba错误这样的描述,但是MS Website给出了以下事件描述:
您可以将DataErr参数与Error函数一起使用来映射 编号为相应的错误消息
但实际上并没有给出这样的例子,我正在努力弄明白。
具体情况是用户将更新子窗体中的记录,某些字段可能会破坏参照完整性规则,该编号只会告诉我参考完整性规则已被破坏,而描述会给我表名称,这允许我给出与发生错误的字段有关的规定性错误消息
有一种简单的方法吗?
答案 0 :(得分:2)
创建一个单独的函数来执行所有验证,并向用户发送任何遗漏的消息。在表单的beforeupdate事件中运行它,并在需要时取消该事件。这可能会消除你的许多form_error。在form_error事件中,您可以调用相同的函数。它已发现问题,禁止默认消息。如果需要,弹出的任何其他错误都可以单独处理。
答案 1 :(得分:1)
通常只是将数字传递给错误以获取描述:
MsgBox Error(DataErr)
答案 2 :(得分:1)
据我所知,除了一个例外,@ AVG的解决方案可能是最佳的解决方法。也就是说,@ AVG可能最好的解决方法是:尝试在Form_BeforeUpdate
事件中捕获错误;并(可能根据您的需要)取消Form_BeforeUpdate
中的活动。
但是,最好不要在Form_Error
级别抑制默认错误。如果您在Form_BeforeUpdate
处捕获并取消了该错误,则该错误不会在Form_Error
处出现。因此,在这种情况下,无需抑制Form_Error
处的错误。但是,如果等待中存在另一种参照完整性违规(例如,类别/组织违规,而不是类别/子类别违规),那么您就没有想到要以开发人员身份进行处理,那么{{{ 1}}会提醒您。您不想因为未发现的错误而隐藏消息。
下面,我提供此变通方法的示例代码。
我还讨论了Form_Error
看起来像是一种可能的解决方案,但还不完全可行。也就是说,它可以用于将AccessError(DataErr)
号映射到消息。这部分有用。但是,不幸的是,消息是变量 un取代的版本。因此,例如,我们不能在代码中使用DataErr
来查询特定的参照完整性违规消息。
当用户通过以下形式触发AccessError(DataErr)
事件:违反了参照完整性(您已完全设置为防止在无效数据状态下进行此类尝试);违反了在表级别设置的验证规则;否则(?)会产生数据错误。
但是,返回的默认消息可能对用户不友好。例如,在涉及到参照完整性的情况下...
您不能添加或更改记录,因为表'CategorySubcategory'中需要相关记录。
在此示例中,表“ CategorySubcategory”表示表“ Category”和“ CategorySubcategory”之间的多对多关系,定义了属于特定类别的特定子类别。 (在我的示例中)在CategorySubcategory中还表示某些类别没有子类别。
所需要的是一种用用户友好的消息代替用户不友好的消息的方法。为此,可以方便地查询默认错误消息的出现,抑制它并替换您自己的错误消息。
(据我所知),我们在Form_Error
中查询默认消息的最接近值为Form_Error
。与AccessError(DataErr)
不同,Error(DataErr)
承诺
...返回与Microsoft Access相关的描述性字符串或 DAO错误 [已添加强调]
[并且保证您可以]使用AccessError方法从表单的Error事件中返回描述性字符串。
因此,您可能会想做类似的事情,如果您可以做类似的事情,那将会很方便。
AccessError
Private Sub Form_Error(DataErr As Integer, Response As Integer)
If AccessError(DataErr) Like "*CategorySubcategory*" Then
MsgBox "[My user friendly message] Choose the right Subcategory given the Category; or change the Category.", vbOKOnly Or vbExclamation
Response = acDataErrContinue ' Suppress default message
End If
End Sub
可以工作吗?但是,事实证明AccessError
仅返回错误消息的变量 un取代版本,而不返回用户在运行时看到的变量取代消息。例如AccessError
返回类似...
您不能添加或更改记录,因为表'|'中需要相关记录。
...而不是...
您不能添加或更改记录,因为表'CategorySubcategory'中需要相关记录。
为证明此情况触发了 data 错误(例如,通过违反参照完整性),
AccessError
观察两个:Private Sub Form_Error(DataErr As Integer, Response As Integer)
' For some reason you'll need to call AccessError(DataErr) before Error(DataErr)
Debug.Print "AccessError(DataErr): ", AccessError(DataErr)
Debug.Print "Error(DataErr): ", Error(DataErr)
End Sub
返回特定消息,其中AccessError
返回无用的通用“应用程序定义或对象定义的错误”; Error
返回错误消息的变量 un取代版本。
@Hello World正确引用了MS Docs > ... > Form.Error event (Access)
您可以将DataErr参数与Error函数一起使用,以将数字映射到相应的错误消息
即使用AccessError
代替了AccessError
,@ Hello World的哀叹仍然是公平的...
[MS docs not]实际上给出了一个例子,我正在努力找出答案。
Error
号MS文档作者可能想到的是类似以下的代码
DataErr
要使用该代码,请创建一个新的数据库,将代码放入模块中,将光标置于代码中间,然后按F5键(以运行它)。将创建一个表Function AccessAndJetErrorsTable() As Boolean
' Source: Access 2000 Help "Determine the Error Codes Reserved by Microsoft Access
' and the Microsoft Jet Database Engine"
Const strTable As String = "zttblAccessAndJetErrors"
Dim cat As New ADOX.Catalog
Dim tbl As New ADOX.Table
Dim cnn As ADODB.Connection
Dim rst As New ADODB.Recordset, lngCode As Long
Dim strAccessErr As String
Const conAppObjectError = "Application-defined or object-defined error"
On Error GoTo Error_AccessAndJetErrorsTable
Set cnn = CurrentProject.Connection
' Create Errors table with ErrorNumber and ErrorDescription fields.
tbl.Name = strTable
tbl.Columns.Append "ErrorCode", adInteger
tbl.Columns.Append "ErrorString", adLongVarWChar
Set cat.ActiveConnection = cnn
cat.Tables.Append tbl
' Open recordset on Errors table.
rst.Open strTable, cnn, adOpenStatic, adLockOptimistic
' Loop through error codes.
For lngCode = 0 To 35000
On Error Resume Next
' Raise each error.
strAccessErr = AccessError(lngCode)
DoCmd.Hourglass True
' Skip error numbers without associated strings.
If strAccessErr <> "" Then
' Skip codes that generate application or object-defined errors.
If strAccessErr <> conAppObjectError Then
' Add each error code and string to Errors table.
rst.AddNew
rst!ErrorCode = lngCode
' Append string to memo field.
rst!ErrorString = strAccessErr
rst.Update
End If
End If
Next lngCode
' Close recordset.
rst.Close
DoCmd.Hourglass False
RefreshDatabaseWindow
MsgBox strTable & " errors table created."
AccessAndJetErrorsTable = True
Exit_AccessAndJetErrorsTable:
Exit Function
Error_AccessAndJetErrorsTable:
MsgBox Err & ": " & Err.Description
AccessAndJetErrorsTable = False
Resume Exit_AccessAndJetErrorsTable
End Function
,您可以在其中查找Access和Jet错误消息的所有变量 un取代的版本;并将它们与一个zttblAccessAndJetErrors
数字相对应。
该代码将为您提供错误消息的最新列表。但是,作为替代,您可以只查找发布该资源的在线资源。例如。 FMS > Microsoft Access 2010 Error Numbers and Descriptions
因此,通过DataErr
或在线查找,您现在可以确定与测试期间看到的错误消息最接近的zttblAccessAndJetErrors
号。这样我们就可以做类似...
DataErr
也就是说,我们不直接在Private Sub Form_Error(DataErr As Integer, Response As Integer)
Select Case DataErr
Case 3201
' "You cannot add or change a record because a related record is required in table '|'."
MsgBox "[My user friendly message] Choose the right Subcategory given the Category; or change the Category.", vbOKOnly Or vbExclamation
Response = acDataErrContinue ' Suppress default message
End Select
End Sub
中使用AccessError
返回消息。而是我们使用了Form_Error
(或依靠其他人使用过的)来生成DataErr / Message映射。在AccessError
中,我们仅继续与Form_Error
数字匹配。但是现在我们可以将相关消息复制为我们的DataErr
号的注释。
但是,至少在这种参照完整性(DataErr 3201)的情况下,我们的问题仍然存在。如果像上面的代码一样,针对特定的引用完整性违例(例如类别/子类别不匹配)取消了默认消息,则可能会掩埋其他特定的引用完整性违例。例如。如果针对用户选择的类别和组织发生了另一个参照完整性违规,则上述代码将错误地(以用户友好的方式)错误地表示发生了类别/子类别违规。
据我所知,@ AVG的解决方案可能是最好的解决方法,只有一个例外。也就是说,@ AVG可能最好的解决方法是:尝试在DataErr
事件中捕获错误;并(可能根据您的需要)取消Form_BeforeUpdate
中的活动。
但是,最好不要在Form_BeforeUpdate
级别抑制默认错误。如果您在Form_Error
处捕获并取消了该错误,则该错误不会在Form_BeforeUpdate
处出现。因此,在这种情况下,无需抑制Form_Error
处的错误。但是,如果等待中存在另一种参照完整性违规(例如,类别/组织违规,而不是类别/子类别违规),那么您就没有想到要作为开发人员来处理,那么{{{ 1}}会提醒您。您不想因为未发现的错误而隐藏消息。
因此,就我而言,解决方法代码看起来像(必须按照@Hello World的建议“沿DLookup路线走”)。
Form_Error
答案 3 :(得分:0)
我总是使用下面的代码模式,以便用户可以获得正确的错误消息,然后他们可以向我传达以了解原因。
<img ng-src="{{ a.hero }}"></img>
对代码中使用的每个Private Sub cmdSearch_Click()
On Error GoTo Sub_Err
--Your code here---
'errors catching stuff
Sub_Exit:
Exit Sub
Sub_Err:
MsgBox Error$
Resume Sub_Exit
End Sub
使用相同的内容。