【问题标题】:Vba two different Error Handlers in one procedureVba 在一个过程中有两个不同的错误处理程序
【发布时间】:2021-10-04 13:53:43
【问题描述】:

我对 vba 中的两个单独的错误处理程序有疑问。两者都与查找两个单独的工作簿是否打开有关?

Sub ErrHandler()
    wbsource_name=ThisWorkbook.Worksheets("Sheet1").Range("A1").Value
    wbdest_name=ThisWorkbook.Worksheets("Sheet1").Range("B1").Value
    On Error GoTo Here
    Set wb_source=Workbooks(wbsource_name)
    Here:
    MsgBox "Open main file"
    Exit Sub

   'I want here to stop first err handler
   'The next file to be opened(or looked if is open)
   'So if first file is open, but second not. It again gives the first error handler message

    On Error GoTo 0
    On Error GoTo Here2
    Set wb_destination=Workbooks(wbdest_name)
    Here2:
    MsgBox "Open UPO file"

我已经使用 On error GoTo 0 来中和第一个错误处理程序,但不幸的是它不起作用。我也尝试过(代码行) On Error GoTo 0 使用 On error Resume Next...我该如何解决?任何想法......在一个子过程中使用两个不同的错误处理程序。先谢谢了

【问题讨论】:

    标签: vba error-handling


    【解决方案1】:

    创建工作簿引用

    Option Explicit
    
    Sub TestOpenWorkbooks()
        
        Dim wb As Workbook: Set wb = ThisWorkbook
        Dim ws As Worksheet: Set ws = wb.Worksheets("Sheet1")
        Dim swbName As String: swbName = ws.Range("A1").Value
        Dim dwbName As String: dwbName = ws.Range("B1").Value
        
        On Error Resume Next
        Dim swb As Workbook: Set swb = Workbooks(swbName)
        On Error GoTo 0
        If swb Is Nothing Then
            MsgBox "Open main file."
            Exit Sub
        End If
        
        On Error Resume Next
        Dim dwb As Workbook: Set dwb = Workbooks(dwbName)
        On Error GoTo 0
        If dwb Is Nothing Then
            MsgBox "Open UPO file."
            Exit Sub
        End If
    
        MsgBox "Files open. Ready to continue."
    
    End Sub
    
    Sub TestOpenWorkbooksImproved()
        
        Dim wb As Workbook: Set wb = ThisWorkbook
        Dim ws As Worksheet: Set ws = wb.Worksheets("Sheet1")
        Dim swbName As String: swbName = ws.Range("A1").Value
        Dim dwbName As String: dwbName = ws.Range("B1").Value
        
        Dim wbPath As String: wbPath = "C:\Test\"
        
        ' This will work either way: open or not open.
        Dim swb As Workbook: Set swb = Workbooks.Open(wbPath & swbName)
        Dim dwb As Workbook: Set dwb = Workbooks.Open(wbPath & dwbName)
    
        MsgBox "Files open. Ready to continue."
    
    End Sub
    

    编辑

    Sub TestOpenWorkbooksFunction()
        
        Dim wb As Workbook: Set wb = ThisWorkbook
        Dim ws As Worksheet: Set ws = wb.Worksheets("Sheet1")
        Dim swbName As String: swbName = ws.Range("A1").Value
        Dim dwbName As String: dwbName = ws.Range("B1").Value
        
        Dim swb As Workbook: Set swb = RefWorkbook(swbName)
        If swb Is Nothing Then
            MsgBox "Open main file."
            Exit Sub
        End If
        
        Dim dwb As Workbook: Set dwb = RefWorkbook(dwbName)
        If dwb Is Nothing Then
            MsgBox "Open UPO file."
            Exit Sub
        End If
    
        MsgBox "Files open. Ready to continue."
    
    End Sub
    
    Function RefWorkbook( _
        ByVal WorkbookName As String) _
    As Workbook
        On Error Resume Next
        Set RefWorkbook = Workbooks(WorkbookName)
        On Error GoTo 0
    End Function
    
    Sub RefWorkbookTEST()
        Dim wb As Workbook: Set wb = RefWorkbook("?")
        If wb Is Nothing Then
            Debug.Print "Nope"
        Else
            Debug.Print wb.Name
        End If
    End Sub
    

    【讨论】:

    • 代码对我来说太长而且难以理解,我设法将第二个工作簿的错误更改为 On Error Got To 0 到 On Error GoTo -1。还是谢谢!
    • 我建议您再尝试一下,因为它说明了 VBA 中的关键错误处理。正式地,VBA On Error Statement 中没有On Error GoTo -1。此外,您可能会从 Chip Pearson 的 Error Handling in VBA 页面学到很多东西。
    • 哇!非常感谢资源!我一定会看的。另外,你们都在程序中使用了UDFunctions...我从不使用udf,但我知道如何编写它们。是否有任何必要性,或者您确切知道 UDF 函数的位置。如果您能就在哪里使用 UDF 提供一些资源,我将不胜感激。非常感谢!)
    • "UDF" 通常保留给打算从工作表上的范围调用的 VBA 函数。这里的答案都没有使用 UDF - 只是一个常规的 VBA 函数(Sub 和 Function 之间的主要区别只是 Function 返回一个值而 Sub 没有)。因此,如果你想get 一些东西,你会调用一个 Function:如果你想 do 一些东西,你会调用一个 Sub。
    【解决方案2】:

    我更喜欢将可能产生错误的操作推送到单独的方法中(尤其是在主代码中重复该操作)。

    Sub Tester()
    
        Dim wbSrc As Workbook, wbDest As Workbook, wbsource_name As String, wbdest_name As String
    
        wbsource_name = ThisWorkbook.Worksheets("Sheet1").Range("A1").Value
        wbdest_name = ThisWorkbook.Worksheets("Sheet1").Range("B1").Value
        
        Set wbSrc = GetOpenWorkbook(wbsource_name, "Workbook '" & wbsource_name & "' must be open")
        If wbSrc Is Nothing Then Exit Sub
        
        Set wbDest = GetOpenWorkbook(wbdest_name, "Workbook '" & wbdest_name & "' must be open")
        If wbDest Is Nothing Then Exit Sub
          
    End Sub
    
    'Return an open workbook given its name, or Nothing if not found
    '  Optional message `msgMissing` to show if not found
    Function GetOpenWorkbook(wbName As String, Optional msgMissing As String = "") As Workbook
        On Error Resume Next
        Set GetOpenWorkbook = Workbooks(wbName)
        On Error GoTo 0
        If GetOpenWorkbook Is Nothing And Len(msgMissing) > 0 Then 
            MsgBox msgMissing
        End If
    End Function
    

    【讨论】:

    • @Tim Williams,我喜欢你的代码的简单性。但是,我通过将 GoTo 0 更改为 GoTo -1 来进行管理。它工作正常。但我也想了解并尝试您的方法。你能帮我理解吗?如果我的变量仅包含工作簿名称,GetOpenWorkbook 会打开工作簿吗?我不使用workbook的路径。
    • @VBasic2008 - 谢谢我已经修复了这两个项目
    • @user16316847 - 不,如果工作簿尚未打开,它就无法打开它,除非有一个固定位置可以“知道”可以从中打开工作簿。您发布的代码只有文件名。
    猜你喜欢
    • 2016-02-25
    • 1970-01-01
    • 2018-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-04
    相关资源
    最近更新 更多