如何使我的 VBA 错误处理更有效率

How can I make my VBA error handling more efficient

我已经为每个循环都写了这个,它给我正在寻找的结果,但是当我单步执行代码时,它似乎在重复错误处理程序,因此 运行ning 非常慢.有没有办法让它 运行 更有效率?

我根本需要错误处理的原因是因为它循环遍历 VLOOKUP 中的值并且某些单元格包含错误。

For Each cell In maxStockRange
        On Error GoTo ErrorValue
        If cell.value = "0" Then
            cell.value = ""
        End If
ErrorValue:
            If cell.Text = "#N/A" Then
                cell.value = ""
            End If
            Resume Next
    Next cell

单元格出错

为什么不更改公式?

=IFERROR(IF(VLOOKUP(...)=0,"",VLOOKUP(...)),"")

想一想您永远不想在数据列中混合使用公式和值。

' This works for values.
maxStockRange.Replace 0, "", xlWhole
maxStockRange.Replace "#N/A", "", xlWhole

' This also works for formulas.
For Each cell In maxStockRange
    Select Case True
    Case IsError(cell), CStr(cell.Value) = "0"
        cell.Value = ""
    Case Else
    End Select
Next cell
Option Explicit

Sub cleanDataUsingErrorHandling()

    Dim cell As Range
    Dim maxStockRange As Range
    
    Set maxStockRange = Sheet1.Range("A1:A4")
    
    For Each cell In maxStockRange
        On Error GoTo ErrorValue
        If cell.Value = "0" Then
            cell.Value = ""
        End If
        GoTo nextIteration
        
ErrorValue:
        If cell.Text = "#N/A" Then
            cell.Value = ""
        End If
        Resume nextIteration
        
nextIteration:
    Next cell
End Sub

VBasic2008 已经为您的问题提供了可靠的解决方案,一般来说,使用 if 语句(如果可能)检查和处理错误并在意外情况下使用错误处理更干净,更好,话虽如此,我觉得需要指出您错误处理中的缺陷。

'ErrorValue:' 被称为 Label Statement,

Statement labels are used to mark a line of code

总结起来就是这样,标签的作用就是指向某行代码

Goto用于跳转到特定的行标签(或行号)

所以基本上你的代码逻辑可以总结如下:

  1. 遍历范围
  2. 如果出现错误 (On Error) 则跳转 (GoTo) 标记为 'ErrorValue' 的代码行并执行其后的代码
  3. 如果cell.value = "0" 那么cell.value = ""

此时,您希望循环会继续下一次迭代并跳转到第 2 步,但实际发生的是标签后面的代码也被执行,因为标签本身不会停止代码(您可以将标签视为保存行号的变量)

Option Explicit

Sub maxStockSub()
On Error GoTo ErrorValue    'you can safely put 'on error' statement after the sub/function defenition

Dim maxStockRange As Range
Dim cell As Range

Set maxStockRange = Range("A1:A10000")

For Each cell In maxStockRange
    If cell.Value = "0" Then
        cell.Value = ""
    ElseIf IsError(cell.Value) Then
        cell.Value = ""
    End If
Next cell

Exit Sub                    'important so that error handling code is only excuted if an error is raised
ErrorValue:
    Debug.Print "#" & Err.Number & ", Desc:" & Err.Description      'here you should handle unexpected errors (like reporting it to the user, or logging it)
    Resume Next
End Sub

备注:

  1. 在你的 sub 顶部使用显式选项,并定义你的变量这样可以使代码执行得更快
  2. 您可以使用 isnumeric()、iserror() 和许多其他函数检查单元格数据类型。
  3. 您可以使用 cint() 或 cdbl() 将单元格值(格式为文本的数字)转换为数字。