On Error 在第一个实例中起作用,在第二个实例中不起作用。漏洞?
On Error works in first and doesn't work in second instance. Bug?
我这里有一个很奇怪的问题。这是代码:
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
我希望它足够清楚它正在尝试做什么(至少 programming-wise)。我有多个 ContentControls(CCs)
具有相同的标题和标签。我最终遇到的问题标有 CAN'T GET OUT,因为,您猜对了 - 我无法退出第二个循环!我以 Out of range error
结束,因为它 运行 来自 CCs
.
更奇怪的是,它确实跳出了第一个循环,该循环具有完全相同的 On Error 语句,被认为指向不同的部分。
是我,还是我只是 - 尽管不太可能 - 运行 到 VBA 中的错误?
无论如何,是否有解决方案或至少有解决方法?
因此,如果您已阅读我的评论并正式回答您的问题,那么这不是错误。
您只需要正确使用 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"
但是正如 link 所建议的那样,您需要处理错误而不是简单地忽略它们。
尝试检查实际错误并找到纠正或避免错误的方法。
您会惊讶地发现您甚至不需要 Error Handling Routine
.
通常,您仅使用错误处理来处理意外或不可预测的情况,例如无法访问驱动器,或发现您无法访问网络。
错误处理不能替代合理的检查,否则可以通过其他方式进行。即集合有一个 Count 属性 ,你可以在遍历它们的项目时使用它,这样可以避免在只有 n 个项目时尝试访问 Item(n+1) 引起的任何错误(这里你 从 Count
知道 n)。或者,使用 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
我这里有一个很奇怪的问题。这是代码:
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
我希望它足够清楚它正在尝试做什么(至少 programming-wise)。我有多个 ContentControls(CCs)
具有相同的标题和标签。我最终遇到的问题标有 CAN'T GET OUT,因为,您猜对了 - 我无法退出第二个循环!我以 Out of range error
结束,因为它 运行 来自 CCs
.
更奇怪的是,它确实跳出了第一个循环,该循环具有完全相同的 On Error 语句,被认为指向不同的部分。 是我,还是我只是 - 尽管不太可能 - 运行 到 VBA 中的错误? 无论如何,是否有解决方案或至少有解决方法?
因此,如果您已阅读我的评论并正式回答您的问题,那么这不是错误。
您只需要正确使用 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"
但是正如 link 所建议的那样,您需要处理错误而不是简单地忽略它们。
尝试检查实际错误并找到纠正或避免错误的方法。
您会惊讶地发现您甚至不需要 Error Handling Routine
.
通常,您仅使用错误处理来处理意外或不可预测的情况,例如无法访问驱动器,或发现您无法访问网络。
错误处理不能替代合理的检查,否则可以通过其他方式进行。即集合有一个 Count 属性 ,你可以在遍历它们的项目时使用它,这样可以避免在只有 n 个项目时尝试访问 Item(n+1) 引起的任何错误(这里你 从 Count
知道 n)。或者,使用 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