VBA错误处理RESUME

时间:2014-01-28 15:57:28

标签: vba ms-access error-handling

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

为了让您了解下面的伪代码应该会发生什么?

  1. 记录被读入数组
  2. 然后将记录插入到表中,其中主键位于数组
  3. 中的唯一标识符上
  4. 如果表中已存在唯一标识符,则数据库(非Access数据库)将引发错误
  5. 错误消息与尝试插入的记录一起被捕获。现在将违规记录放入错误表中供以后查看
  6. 恢复抛出错误消息的位置
  7. 问题是代码在执行查询的地方恢复,而不是在循环开始时再次在这种情况下在行集 rs = cmdSQLData.Execute() 实际上,这意味着它永远试图插入相同的记录

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

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

    PSEUDO CODE

    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
    

    PSEUDO错误处理代码

    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
    

1 个答案:

答案 0 :(得分: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是出于意外错误。您实际上是在逻辑中使用此错误来确定该行是否已存在。如果您希望该行永远不会存在,那么请将其踢到错误处理程序并中止代码。但是,如果您希望有时行已经存在并且最有效的方法是通过尝试插入行来确定,那么您应该在代码体中处理该错误。至少这是我的意见。