On Error在first中起作用,在第二个实例中不起作用。错误?

时间:2015-02-25 06:11:44

标签: vba word-vba

我这里有一个非常奇怪的问题。这是代码:

reqLang = "ENG"
    Select Case reqLang
        Case "CRO", "ENG"
            'first loop -------------------------------------
            On Error GoTo reqLangVisible
            i = 1
            'Loop until ccCROENG's are all hidden and then go to reqLangVisible.
            Do
                ActiveDocument.SelectContentControlsByTag("ccCROENG")(i) _
                    .Range.Font.Hidden = True 'hides all CCs
                i = i + 1
            Loop
reqLangVisible:
            'second loop -------------------------------------
            On Error GoTo langOut
            i = 1
            'Loop until ccreqLang's are all visible and then go to langOut.
            Do
                ActiveDocument.SelectContentControlsByTitle("cc" & reqLang)(i) _
                    .Range.Font.Hidden = False 'activates reqLang CCs
                i = i + 1
            Loop ' CAN'T GET OUT -----------------------------------
        Case "CROENG"
            i = 1
            'Loop until ccCROENG's are all visible and then go to langOut.
            Do
                On Error GoTo langOut
                    ActiveDocument.SelectContentControlsByTag("ccCROENG")(i) _
                        .Range.Font.Hidden = False 'Shows all CCs
                i = i + 1
            Loop
    End Select
langOut:
MsgBox "Success!" '------- yeah, not really.
Stop

我希望它能够清楚地了解它(至少是编程方式)。我有多个ContentControls(CCs)具有相同的标题和标签。我最终遇到的问题标有 CAN' T GET OUT ,因为,你猜对了 - 我无法得到第二个循环!我最终得到了Out of range error,因为它用完了CCs

甚至更奇怪的是它确实离开了第一个循环,它具有完全相同的On Error语句,被认为指向不同的部分。 是我,还是我只是 - 但不太可能 - 遇到VBA中的错误? 在任何情况下,是否有解决方案或至少有解决方法?

2 个答案:

答案 0 :(得分:1)

通常,您只使用错误处理来处理意外或不可预测的情况,例如无法访问驱动器或发现您没有网络访问权限。

错误处理不能替代合理的检查,否则可以进行。集合有一个Count属性,你可以在循环它们的项目时使用它,所以避免因只有n个项目时尝试访问Item(n + 1)而导致的任何错误(这里你知道 n来自Count)。或者,使用For Each循环。

这里有一些示例代码,演示如何使用两种方法来循环控件:

Sub Tester()

    Dim cc1 As ContentControls, cc2 As ContentControls
    Dim c, i As Long

    With ActiveDocument
        Set cc1 = .SelectContentControlsByTag("tbTag")
        Set cc2 = .SelectContentControlsByTitle("tbTitle")
    End With

    Debug.Print "cc1 has " & cc1.Count
    Debug.Print "cc2 has " & cc2.Count

    'use the Count property
    For i = 1 To cc1.Count
        Set c = cc1(i)
        c.Range.Font.Hidden = True
    Next i

    'use a For Each loop
    For Each c In cc2
        c.Range.Font.Hidden = False
    Next c

End Sub

这是为此类流控制设计的场景类型。

应用于原始代码:

Sub Tester2()
    Dim reqLang, cc As ContentControls, c

    reqLang = "ENG"

    Select Case reqLang

        Case "CRO", "ENG"

            Set cc = ActiveDocument.SelectContentControlsByTag("ccCROENG")
            SetTextHidden cc, True

            Set cc = ActiveDocument.SelectContentControlsByTitle("cc" & reqLang)
            SetTextHidden cc, False

        Case "CROENG"

            Set cc = ActiveDocument.SelectContentControlsByTag("ccCROENG")
            SetTextHidden cc, False

    End Select

    MsgBox "Success!" '-- yeah really

End Sub

Sub SetTextHidden(cc As ContentControls, MakeHidden As Boolean)
    Dim c
    For Each c In cc
        c.Range.Font.Hidden = MakeHidden
    Next c
End Sub

答案 1 :(得分:0)

因此,如果您已阅读我的评论并正式回答您的问题,那么这不是错误。
您只需要正确使用Error Handling Routines即可。
你要做的事情有点像下面。 HTH。

Select Case reqlang

Case "CRO", "ENG"
    On Error Resume Next '~~> ignores the error when encountered
    '~~> Your loop which possibly creates the error goes here
    On Error Goto 0 '~~> resets the actively triggered error handling

Case "CROENG"
    On Error Resume Next '~~> ignores the error when encountered
    '~~> Your loop which possibly creates the error goes here
    On Error Goto 0 '~~> resets the actively triggered error handling

End Select

MsgBox "Success"

但正如链接所示,您需要处理错误而不是简单地忽略它们。
尝试检查实际错误并找到解决方法或避免错误。
你会惊讶的是你甚至不需要Error Handling Routine