VBA Excel 简单错误处理
Posted
技术标签:
【中文标题】VBA Excel 简单错误处理【英文标题】:VBA Excel simple Error Handling 【发布时间】:2015-08-09 22:14:46 【问题描述】:我已尽可能多地上网(Microsoft 支持网站除外,该网站由于某种原因在工作中被阻止)。我试图简单地跳过一个错误。我在此处编写的代码已简化,但应该以相同的方式工作。
我的代码应该做什么: 我的一个潜艇在循环中创建形状并命名它们(btn_1、btn_2 等)。但在创建它们之前,它会调用一个尝试删除它们的子程序,以免创建重复项。这个子循环遍历(btn_1、btn_2 等)并使用以下命令删除形状:
for i = 1 to (a certain number)
Set shp = f_overview.Shapes("btn_" & i)
shp.delete
next
当然,形状不能被删除,因为它根本不存在。我发现大多数时候,推荐的修复方法是在设置形状之前添加(下一个错误恢复),因为我收到一个错误说它不存在。我已经在循环内、循环之前等尝试过,如下所示:
for i = 1 to (a certain number)
On Error Resume Next
Set shp = f_overview.Shapes("btn_" & i)
shp.delete
next
据我所知,如果形状不存在,它应该直接循环,但无论我是否添加下一个错误恢复,我仍然会遇到相同的错误!我做错了什么?
编辑:当形状确实存在时没有错误。
【问题讨论】:
【参考方案1】:试试:
On Error Resume Next
for i = 1 to (a certain number)
Set shp = f_overview.Shapes("btn_" & i)
if err<>0 then err.clear else shp.delete
next
on Error Goto 0
【讨论】:
【参考方案2】:听起来您设置了错误的错误捕获选项。在 VBA 编辑器中,选择 Tools -> Options
。在打开的窗口中,选择General tab
,然后选择Break on Unhandled Errors
单选按钮。这应该允许 Excel 正确处理 On Error Resume Next
命令。
我怀疑你选择了Break on All Errors
。
【讨论】:
谢谢!我一直在尝试其他回答者的建议,但都失败了。这就是为什么尽管他们也提供了有价值的信息! @DavidGrand'Maison 我同意在其他答案中进行的错误处理更干净、更好。但是您的原始代码应该可以工作。【参考方案3】:与其尝试盲目地删除形状和跳过错误,不如遍历已知形状列表并删除它们。那么您就不必担心On Error Resume Next
会经常最终被滥用。
Sub Test(TheSheet As Worksheet)
Dim Shp as Shape
For Each Shp in TheSheet.Shapes
If left(Shp.Name, 4) = "btn_" Then
Shp.Delete
End if
Next
End Sub
如果要删除所有形状,请删除 If
语句。如果要删除多个不同命名的形状,请适当修改If
语句。
【讨论】:
太棒了!这是我将选择的方式。谢谢你的修复。 +1 回答,即使您没有解释如何使用错误处理:-) 您在缺少错误处理细节方面是正确的 - 这个循环不需要它,尤其是您的想法。 Mat's Mug 在一般的错误处理方面做得很好。 没关系,@FreeMan,3 个月后,有一个随机的路过投票! :)【参考方案4】:我发现大多数时候,推荐的修复方法是在设置形状之前添加(下一个错误恢复),因为我收到一个错误说它不存在。
不!
处理运行时错误的推荐方法是不将它们推到地毯下并继续执行,就像什么都没发生一样 - 这正是 On Error Resume Next
所做的。
避免运行时错误的最简单方法是检查错误条件,并避免执行导致 100% 失败率的代码,例如尝试在 Nothing
的对象引用上运行方法:
For i = 1 To (a certain number)
Set shp = f_overview.Shapes("btn_" & i)
If Not shp Is Nothing Then shp.Delete
Next
如果您无法检查错误情况并且必须处理错误,推荐的方法是处理它们:
Private Sub DoSomething()
On Error GoTo CleanFail
'...code...
CleanExit:
'cleanup code here
Exit Sub
CleanFail:
If Err.Number = 9 Then 'subscript out of range
Err.Clear
Resume Next
Else
MsgBox Err.Description
Resume CleanExit
End If
End Sub
【讨论】:
++ 关于正确的错误处理:) @SiddharthRout 是的,除了我没有测试它,现在我越想它,我越相信这个作业会抛出一个index out of range
错误,在这种情况下 FreeMan's answer 有一个更好的解决方案。
那;没问题 :) 编辑上面的代码。我的评论是您在帖子底部显示的正确错误处理。我确实在我的帖子中提到了这一点:)
@SiddharthRout 已编辑,...没有窃取任何人的答案:)
无需在 Resume Next 之前明确地“Err.Clear”。至于 MS Docs “在错误处理例程中的 Exit Sub、Exit Function、Exit Property 或 Resume Next 语句之后,Err 对象的属性被重置为零或零长度字符串 ("")。使用任何形式的错误处理例程之外的 Resume 语句不会重置 Err 对象的属性。Clear 方法可用于显式重置 Err。"【参考方案5】:
只要您了解自己在做什么以及它将如何影响您的代码,使用 OERN(On Error Resume Next)没有任何错误。
在你的情况下,使用 OERN 是完全正常的
Dim shp As Shape
For i = 1 To (a certain number)
On Error Resume Next
Set shp = f_overview.Shapes("btn_" & i)
shp.Delete
On Error GoTo 0
Next
同时确保你不要做类似的事情
On Error Resume Next
<Your Entire Procedure>
On Error GoTo 0
这将抑制所有错误。使用 Matt 所示的正确错误处理
编辑:
这是另一个关于如何使用 OERN 的漂亮示例。此函数检查特定工作表是否存在。
Function DoesWSExist(wsName As String) As Boolean
Dim ws As Worksheet
On Error Resume Next
Set ws = ThisWorkbook.Sheets(wsName)
On Error GoTo 0
If Not ws Is Nothing Then DoesWSExist = True
End Function
如果您愿意,您还可以遍历所有工作表以检查工作表是否存在!
【讨论】:
感谢您的解释!但是,它失败的原因是我的设置错误(请参阅选择的答案)。 ++ 但不幸的是,大多数人不理解使用 OERN 的含义。我喜欢这个首字母缩写词。我留着。以上是关于VBA Excel 简单错误处理的主要内容,如果未能解决你的问题,请参考以下文章
Excel VBA 自动过滤器然后更改字段值并填写错误处理空白单元格的可能性