【问题标题】:Access VBA: Is it possible to reset error handling?Access VBA:是否可以重置错误处理?
【发布时间】:2010-09-24 18:16:27
【问题描述】:

我在我的程序的第一部分使用

On Error GoTo start

假设在我的第二部分我再次使用

On Error Resume Next

第二个错误陷阱不会被激活,因为第一个错误陷阱仍然处于活动状态。有什么方法可以在第一个错误处理程序使用后停用它?

Set objexcel = CreateObject("excel.Application")
                     objexcel.Visible = True
                     On Error GoTo Openwb
                     wbExists = False
                     Set wbexcel = objexcel.Workbooks.Open("C:\REPORT3.xls")
                     Set objSht = wbexcel.Worksheets("Sheet1")
                     objSht.Activate
                     wbExists = True
Openwb:
                     
                     On Error GoTo 0
                     If Not wbExists Then
                     objexcel.Workbooks.Add
                     Set wbexcel = objexcel.ActiveWorkbook
                     Set objSht = wbexcel.Worksheets("Sheet1")

                     End If
                     
                     On Error GoTo 0
                                         
Set db = DBEngine.opendatabase("C:\book.mdb")
Set rs = db.OpenRecordset("records")

Set rs2 = CreateObject("ADODB.Recordset")
rs2.ActiveConnection = CurrentProject.Connection


For Each tdf In CurrentDb.TableDefs
   
   If Left(tdf.Name, 4) <> "MSys" Then
        rs.MoveFirst
        strsql = "SELECT * From [" & tdf.Name & "] WHERE s=15 "

        Do While Not rs.EOF
            On Error Resume Next
            
            rs2.Open strsql 

在执行最后一条语句时,我想忽略错误并转到下一个表,但错误处理似乎不起作用。

【问题讨论】:

    标签: vba ms-access error-handling


    【解决方案1】:

    On error goto 0 交给 Visual Basic 进行错误处理(在一般消息框中)

    On error goto label 会将您的代码重定向到 label:

    On error resume next 将忽略错误并继续

    Resume next出现错误后将代码重定向到下一行

    表示指令的组合,如

        On Error goto 0
        ...
        On Error goto 0
    

    没有意义

    如果你想重定向“错误”指令,你必须这样做:

        Do While Not rs.EOF
            
            On Error Resume Next
            rs2.Open strsql
            On error Goto 0
    
            rs2.moveNext
    
        Loop
    

    如果您想将错误重定向到标签(用于处理或其他),然后返回发生错误的代码,您必须编写如下内容:

        On error goto label
        ...
        ...
        On error goto 0
        exit sub (or function)
    
        label:
        ....
        resume next
        end function
    
    

    但我真的建议您对错误管理更加严格。你首先应该能够做这样的事情:

        Set objexcel = CreateObject("excel.Application")
        objexcel.Visible = True
    
        On Error GoTo error_Treatment
        wbExists = False
        Set wbexcel = objexcel.Workbooks.Open("C:\REPORT3.xls")
        Set objSht = wbexcel.Worksheets("Sheet1")
        objSht.Activate
        wbExists = True
        On error GoTo 0
    
        Set db = DBEngine.opendatabase("C:\book.mdb")
        Set rs = db.OpenRecordset("records")
    
        Set rs2 = CreateObject("ADODB.Recordset")
        rs2.ActiveConnection = CurrentProject.Connection
    
        For Each tdf In CurrentDb.TableDefs
            ....
            'there are a number of potential errors here in your code'
            'you should make sure that rs2 is closed before reopening it with a new instruction'
            'etc.'
        Next tdf
    
        Exit sub
    
        error_treatment:
        SELECT Case err.number
           Case **** '(the err.number raised when the file is not found)'
               objexcel.Workbooks.Add
               Set wbexcel = objexcel.ActiveWorkbook
               Set objSht = wbexcel.Worksheets("Sheet1")
               Resume next 'go back to the code'
           Case **** '(the recordset cannot be opened)'
               ....
               ....
               Resume next 'go back to the code'
           Case **** '(whatever other error to treat)'
               ....
               ....
               Resume next 'go back to the code'
           Case Else
               debug.print err.number, err.description '(check if .description is a property of the error object)'
               'your error will be displayed in the immediate windows of VBA.' 
               'You can understand it and correct your code until it runs'
           End select
        End sub
    

    下一步将是预测代码中的错误,以便不会引发 err 对象。例如,您可以编写一个像这样的通用函数:

        Public function fileExists (myFileName) as Boolean
    

    然后您可以通过测试您的 xls 文件的存在来在您的代码中利用此功能:

        if fileExists("C:\REPORT3.xls") Then
            Set wbexcel = objexcel.Workbooks.Open("C:\REPORT3.xls")
        Else
           objexcel.Workbooks.Add
           Set wbexcel = objexcel.ActiveWorkbook
        Endif        
        Set objSht = wbexcel.Worksheets("Sheet1")
        objSht.Activate
    

    你不再需要你的 wbExist 变量了...

    同样,您应该预料到您的记录集没有记录的情况。在测试之前写下 rs.MoveFirst 可能会引发错误。然后你应该写

        If rs.EOF and rs.BOF then
        Else
            rs.moveFirst
            Do while not rs.EOF
                 rs.moveNext
            Loop
        End If
    

    【讨论】:

      【解决方案2】:

      您需要清除错误。试试把这段代码放进去:

      If Err.Number > 0 Then
          Err.Clear
      End If
      

      您还可以使用 Err.Number 来处理特定的错误情况。

      【讨论】:

      • 这似乎也不起作用。如果将 excel 的第一部分放在单独的子目录中,则此代码有效,但我现在希望它像这样。
      • 我认为丢弃所有错误并不是一个好主意。如果您丢弃了一个您不期望的错误怎么办?
      • 大卫,说得好。这就是为什么我说你可以使用 Err.Number 来处理特定的错误情况。而不是做一个通用的清除所有,只要清除错误是否是您所期望的。
      【解决方案3】:

      避免错误几乎总是比处理错误更好。例如:

      Set objexcel = CreateObject("excel.Application")
      objexcel.Visible = True
      
      'On Error GoTo Openwb '
      'wbExists = False '
      
      If Dir("C:\REPORT3.xls") = "" Then
          objexcel.Workbooks.Add
          Set wbexcel = objexcel.ActiveWorkbook
          Set objSht = wbexcel.Worksheets("Sheet1")
      Else
          Set wbexcel = objexcel.Workbooks.Open("C:\REPORT3.xls")
          Set objSht = wbexcel.Worksheets("Sheet1")
      End If
      
      objSht.Activate
      'wbExists = True '
      

      【讨论】:

      • 感谢您完成了这项工作。但是作为一个疑问,是否有可能在使用后取消错误处理,然后再继续程序。
      • Quib​​ble:在 VBA 中,在测试零长度字符串时使用 vbNullString 而不是 "" 会更有效,因为 Access 常量已经分配了内存。这个常量无关紧要,但是养成这个习惯是很好的,所以你总是在循环中使用 vbNullString。
      • @tksy :“On Error GoTo 0”正是这样做的。它将 VBA 返回到其通常的错误处理。这并不意味着我认为您的问题所暗示的“On Error GoTo Start”。
      • 您的评论是正确的,但有些地方无法做到这一点。无论如何,可以避免这种“错误”处理的人应该尝试使用它
      • 这在技术上是正确的,但不能回答问题。这是一个简单的问题,真的:“有没有办法重置错误处理”
      【解决方案4】:

      试试

      On Error Goto 0
      

      更多帮助请看这里:http://msdn.microsoft.com/en-us/library/bb258159.aspx

      【讨论】:

      • 你能把你的源代码贴在这里吗?也许你错误地使用了 on error 语句。
      【解决方案5】:

      答案和解决方案之间是有区别的。有时我们只需要一个答案,感谢警告,让我们从经验中了解到这实际上并不是一个好的解决方案。话虽如此,我找到了this

      您需要使用 On Error GoTo -1 或 Err.Clear 来重置错误捕获。

      查看我几个月前发布的this answer以获得更详细的说明。

      【讨论】:

        猜你喜欢
        • 2021-09-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-18
        • 1970-01-01
        • 2013-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多