On Error处理程序后,Excel VBA仍会中断

Kai*_*Kai 0 excel vba excel-vba

我有一个非常简单的代码循环遍历一列数据并向Collection添加唯一值.

它是VBA,所以当然Collection缺少一个Exists函数(谁曾经想要那个?),我宁愿避免迭代列中每个单元格的整个集合,我决定采用错误处理方法 - 尝试从集合中检索项目,捕获发生的错误(如果它不存在)并添加它:

'Trucated the code slightly, I know I should be checking the actual error code, but omitted that for brevity

Dim r As Range
Set r = MySheet.Range("B2") 'First cell in column

Dim uniqueValues As New Collection
Do While r.Value <> ""
    On Error GoTo ItemExists
    'If r.Value doesn't exist in the collection, throws an error
    uniqueValues.Add(Item:=r.Value, Key:=r.Value) 
ItemExists:
    r.Offset(1)
Loop
Run Code Online (Sandbox Code Playgroud)

问题?Excel中似乎完全无视On Error线,打破了代码,并抛出了Continue/ End/ Debug对话框不管.

我已经检查了VBA中的选项,它已正确设置为 Break on Unhandled Errors.

知道为什么会这样吗?

Joe*_*Joe 5

您可以使用On Error Resume Next,但最好将错误处理封装在自己的Sub或Function中.例如:

Private Sub AddIfNotPresent(Coll As Collection, Value As Variant, Key As Variant)
    On Error Resume Next
    Coll.Add Item:=Value, Key:=Key
End Sub
Run Code Online (Sandbox Code Playgroud)

您可以使用如下:

Do While r.Value <> ""
    AddIfNotPresent uniqueValues, r.Value, r.Value
    r = r.Offset(1)
Loop
Run Code Online (Sandbox Code Playgroud)

您的问题的原因在VBA文档中描述On Error:

"启用"错误处理程序是由On Error语句打开的错误处理程序; "活动"错误处理程序是处理错误的已启用处理程序.如果错误处理程序处于活动状态时发生错误(在错误发生与Resume,Exit Sub,Exit Function或Exit Property语句之间),则当前过程的错误处理程序无法处理错误

在第一个错误之后,您没有调用Resume或退出过程,因此错误处理程序无法处理后续错误.

UPDATE

来自评论:

我讨厌推广使用On Error Resume Next ...

我可以同情这个POV,但是VBA中有一些东西(例如,检查集合中是否存在密钥),你只能通过处理错误来完成.如果在专用辅助方法(子/函数)中执行此操作,则这是一种合理的方法.当然,您可以使用On Error Goto,例如以下内容(上面的变体,用于测试集合是否包含给定键):

Public Function ContainsKey(Coll As Collection, Key As Variant) As Boolean
    On Error GoTo ErrHandler
    Dim v As Variant
    v = Coll(Key)
    ContainsKey = True
    Exit Function
ErrHandler:
    ContainsKey = False
    Exit Function
End Function
Run Code Online (Sandbox Code Playgroud)