【问题标题】:VBA Error Handling RESUMEVBA 错误处理恢复
【发布时间】:2014-02-20 01:01:20
【问题描述】:

我有一段代码从表中读取信息并将其插入到带有主键的表中。第一个表是由许多不同的人输入的用户,第二个是我要清理的表

为了让您了解会发生什么,下面的伪代码应该会有所帮助

  1. 记录被读入数组
  2. 然后将记录插入到表中,其中主键是数组中唯一标识符的主键
  3. 如果表中已存在唯一标识符,则数据库会抛出错误(不是 Access 数据库)
  4. 错误消息与试图插入的记录一起被捕获。违规记录现在被放入错误表以供日后查看
  5. 在抛出错误消息的地方恢复

问题是代码在执行查询的地方恢复,而不是在循环开始时再次在这种情况下在行 Set rs = cmdSQLData.Execute() 实际上,这意味着它永远试图插入相同的记录

在我的错误处理程序中,我将循环增加一条记录,因此它现在尝试插入下一条记录。不幸的是,接下来的简历中没有考虑到这一点

在实践中我想要的是循环在错误处理程序中增加 1,然后循环尝试插入下一条记录

伪代码

intNumberRows = UBound(myArray, 2) + 1 ' number of records/rows in the array
rowcounter = 0


' Append the Rows of local Table to the temp table
For rowcounter = rowcounter To intNumberRows - 1

' Values X Y Z in this case records contained with the array being looped and inserted
    AppendQuery = "INSERT INTO TABLE VALUES(X,Z etc....)
    cmdSQLData.CommandText = AppendQuery
    cmdSQLData.CommandType = adCmdText
    cmdSQLData.CommandTimeout = 60
    Set rs = cmdSQLData.Execute()

Next

伪错误处理代码

ErrorHandler:
If (Len(Err.Description) > 0) Then
    Debug.Print Err.Description
End If

Debug.Print Err.Number
Debug.Print AppendQuery

' Create Error Table For Upload and resume Inserting of records

If (Err.Number = -2147217900) Then
    runfunc = CreateErrorTable(variables)

    If runfunc = True Then
        rowcounter = rowcounter + 1
    Else:
        GoTo EndFunction
    End If
End If

EndFunction:
cn.Close
Set cn = Nothing
Set rs = Nothing
Set cmdSQLData = Nothing

【问题讨论】:

    标签: vba ms-access error-handling


    【解决方案1】:

    这是一个经验法则。永远不要增加 For Next 控制变量。只有循环应该增加它。当我预计会出现错误或在业务逻辑中生成错误时,我会在代码主体中处理该错误。

    Sub InsertRows()
    
        Dim rowcounter As Long
    
        On Error GoTo ErrorHandler
    
        For rowcounter = 1 To 10
            On Error Resume Next
                'Execute query
            On Error GoTo ErrorHandler
    
            If Err.Number = -2147217900 Then
                'Append to error table
            ElseIf Err.Number <> 0 Then
               Err.Raise Err.Number 'reraise error outside of 'resume next'
            End If
        Next rowcounter
    
    ErrorHandler:
        'handle other errors
    
    End Sub
    

    对我来说,ErrorHandler 用于处理意外错误。您实际上是在逻辑中使用此错误来确定该行是否已存在。如果您希望该行永远不会存在,则将其踢到错误处理程序并中止代码。但是,如果您希望有时该行已经存在并且您确定这一点的最有效方法是尝试插入该行,那么您应该在代码正文中处理该错误。至少这是我的看法。

    【讨论】:

    • 嗨,迪克,非常感谢您的建议。关于代码中的错误处理,我有一个小问题。 Resume Next 将在何时执行?它会覆盖 ErrorHandler 吗?
    • On Error Resume Next 行在程序到达该行时执行(或者我没有得到问题)。 On Error Resume Next 错误处理程序。在Resume Next 之后遇到的任何错误基本上都将被忽略。然后一旦达到GoTo ErrorHandler,任何错误都会被重定向到那个ErrorHandler 标签。错误处理基本上有GoTo LabelResume NextGoto 0三种类型。最后一个关闭错误处理,任何错误都会停止程序执行。
    • 嗨,迪克...我已经添加了简历似乎取代了 GoTo ErrorHandler 的代码,所以当我得到第二个相同的 ID 时,它会恢复但它完全忽略 If Err.Number = - 2147217900 段代码。我 debug.print 和错误代码和数字是正确的,只是没有被 If 语句拾取
    • 你是说错误号是-2147217900但If语句返回False? Err.Number 0 然后返回 true 吗?确保您在代码中正确输入了错误号。
    猜你喜欢
    • 2015-06-06
    • 2021-09-01
    • 2015-02-18
    • 2021-06-17
    • 2021-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多