如何使我的 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用于跳转到特定的行标签(或行号)
所以基本上你的代码逻辑可以总结如下:
- 遍历范围
- 如果出现错误 (On Error) 则跳转 (GoTo) 标记为 'ErrorValue' 的代码行并执行其后的代码
- 如果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
备注:
- 在你的 sub 顶部使用显式选项,并定义你的变量这样可以使代码执行得更快
- 您可以使用 isnumeric()、iserror() 和许多其他函数检查单元格数据类型。
- 您可以使用 cint() 或 cdbl() 将单元格值(格式为文本的数字)转换为数字。
我已经为每个循环都写了这个,它给我正在寻找的结果,但是当我单步执行代码时,它似乎在重复错误处理程序,因此 运行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用于跳转到特定的行标签(或行号)
所以基本上你的代码逻辑可以总结如下:
- 遍历范围
- 如果出现错误 (On Error) 则跳转 (GoTo) 标记为 'ErrorValue' 的代码行并执行其后的代码
- 如果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
备注:
- 在你的 sub 顶部使用显式选项,并定义你的变量这样可以使代码执行得更快
- 您可以使用 isnumeric()、iserror() 和许多其他函数检查单元格数据类型。
- 您可以使用 cint() 或 cdbl() 将单元格值(格式为文本的数字)转换为数字。