循环内的运行时错误 91(对象变量或未设置块变量),但代码在循环外工作

以利沙·迪·福尔科

我正在尝试删除所有包含 #REF 文本的行。但是我在对象中出错。

我试图从循环中提取代码并工作。这怎么会发生?是嵌套循环吗?

1)不工作的代码

Sub FindDeleteLoop()
Dim wb1 As Workbook
Dim sh1 As Worksheet
Dim objcell As Range
Dim delrow As Long
Dim i As Long

Set wb1 = ActiveWorkbook

For Each sh1 In wb1.Worksheets
    With sh1

        RowCount = sh1.Cells.Find(What:="*", After:=sh1.Cells(1, 1), LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False).Row

        For i = 1 To RowCount
            On Error GoTo nextcom
            Set objcell = sh1.Cells.Find(What:="*#REF*", After:=sh1.Cells(1, 1), LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)

            objcell.EntireRow.Delete

            Next i

            nextcom:
        End With


    Next
End Sub

然后我在第二个循环之外尝试了相同的操作,并
通过替换获得了2) 工作代码

For Each sh1 In wb1.Worksheets

Set sh1 = wb1.ActiveSheet

我只是不明白这样做的理由。

马修·金东

缩进极具误导性。让我们修复它

For Each sh1 In wb1.Worksheets
    With sh1

        RowCount = sh1.Cells.Find(What:="*", After:=sh1.Cells(1, 1), LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False).Row

        For i = 1 To RowCount
            On Error GoTo nextcom
            Set objcell = sh1.Cells.Find(What:="*#REF*", After:=sh1.Cells(1, 1), LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)

            objcell.EntireRow.Delete

        Next i

nextcom: 
    End With
Next

问题是错误状态永远不会被清除,所以无论何时Range.Find返回Nothing,下一条指令都是非法的:

objcell.EntireRow.Delete 'objcell is Nothing ~> error 91

因此,当 VBA 仍处于错误状态时内部循环继续进行On Error因此忽略下一次迭代的语句 - 当下一次objcell.EntireRow抛出错误 91 时,执行会突然停止。

解决方案是删除这些On Error语句,并使用正常的流控制——也就是说,只有objcell当你知道它持有一个有效的对象引用时才调用一个成员

If Not objcell Is Nothing Then objcell.EntireRow.Delete

代码也有其他问题。Range.Find正在搜索整个工作表:无需迭代每一行。

RowCount = sh1.Cells.Find(What:="*", After:=sh1.Cells(1, 1), LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False).Row

如果sh1是空工作表,这将失败并显示错误 91 ,因为Row成员调用将与Nothing. 考虑这种更安全的方法:

RowCount = sh1.Cells(Rows.Count, 1).End(xlUp).Row

无论如何,我们并不真正关心行数是多少——我们可以继续搜索工作表,直到没有更多结果:

Do
    Set objcell = sh1.Cells.Find(...)
    If Not objcell Is Nothing Then objcell.EntireRow.Delete
Loop While Not objcell Is Nothing

但是回到错误的错误处理。

是不是 On Error GoTo nextcom 处理这个?

正如上面简要提到的,答案是“是”,但有一个警告:如果错误没有被实际处理,那么 VBA 不知道它回到了“快乐的道路”,并且在仍然处于错误状态的时候快乐地继续迭代.

所以问题是您的错误执行路径与正常执行路径交织在一起:每当您设置错误处理程序子例程时,您需要确保错误处理子例程只在错误状态下运行,并且要么实际处理错误状态或退出程序

Err.Clearnextcom:标签和End With后面标签之间添加将清除错误状态并且循环将起作用......但您仍然会有交织在一起的执行路径:如上所示,这表明您正在使用错误处理进行流控制,那就是使代码更难遵循。

这是糟糕的代码,执行路径解开仅用于说明目的(改用上面的Do...While循环!)

    For Each sh1 In wb1.Worksheets
        With sh1

            RowCount = sh1.Cells.Find(What:="*", After:=sh1.Cells(1, 1), LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False).Row

            For i = 1 To RowCount
                On Error GoTo ErrHandler
                Set objcell = sh1.Cells.Find(What:="*#REF*", After:=sh1.Cells(1, 1), LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)

                objcell.EntireRow.Delete

            Next i

        End With
nextcom: '<~ never jump back into a With...End With block
    Next

    Exit Sub '<~ "happy path" ends here
ErrHandler:  '<~ "error path" starts here
    Debug.Assert Err.Number = 91 'execution stops here if that isn't the case
    Resume nextcom '<~ 'Resume' clears the error state

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

运行时错误91:未设置对象变量或With块

来自分类Dev

运行时错误91对象变量或未设置带块变量-使用公共变量

来自分类Dev

运行时错误91对象变量或带块变量的数据库未设置

来自分类Dev

获取运行时错误“ 91”:对象变量或未设置块变量

来自分类Dev

运行时错误'91'; 未设置对象变量或带块变量

来自分类Dev

VBA:运行时错误 91:未设置对象变量或块变量

来自分类Dev

运行时错误 91 - 对象变量或未设置块变量 - VBA

来自分类Dev

检查 excel vba 中是否存在 getelementsbyclassname。运行时错误 91 对象变量或块变量未设置

来自分类Dev

未设置对象变量或With块变量(错误91)

来自分类Dev

在Excel中未设置对象变量或With块变量(错误91)

来自分类Dev

在Excel中未设置对象变量或With块变量(错误91)

来自分类Dev

VBA中的构造方法-运行时错误91“未设置对象变量”

来自分类Dev

Excel VBA运行时错误91对象变量未设置

来自分类Dev

运行时错误91:未在Excel 2013中设置对象变量或带有块变量

来自分类Dev

for循环的C运行时错误

来自分类Dev

运行时无限循环错误

来自分类Dev

for循环的C运行时错误

来自分类Dev

将对象分配给集合:错误“ 91”:对象变量或未设置带块变量

来自分类Dev

VBA错误91:未设置对象变量

来自分类Dev

VBA错误91:未设置对象变量

来自分类Dev

我收到运行时错误“91”:对象变量或块变量未在工作表上设置。可能没有选择工作表?

来自分类Dev

循环和运行时错误中的C ++变量声明

来自分类Dev

VBA错误91:未设置对象变量或含块变量(Excel 2013)

来自分类Dev

VBA错误91:未设置对象变量或With块变量(Excel 2013)

来自分类Dev

未设置对象变量或带块变量(错误91),请协助

来自分类Dev

循环内循环的运行时分析

来自分类Dev

运行for循环时出现奇怪的运行时错误'424'

来自分类Dev

获取运行时错误“91”对象变量 + 整体代码运行状况

来自分类Dev

为范围单元的每个循环运行时避免错误?

Related 相关文章

  1. 1

    运行时错误91:未设置对象变量或With块

  2. 2

    运行时错误91对象变量或未设置带块变量-使用公共变量

  3. 3

    运行时错误91对象变量或带块变量的数据库未设置

  4. 4

    获取运行时错误“ 91”:对象变量或未设置块变量

  5. 5

    运行时错误'91'; 未设置对象变量或带块变量

  6. 6

    VBA:运行时错误 91:未设置对象变量或块变量

  7. 7

    运行时错误 91 - 对象变量或未设置块变量 - VBA

  8. 8

    检查 excel vba 中是否存在 getelementsbyclassname。运行时错误 91 对象变量或块变量未设置

  9. 9

    未设置对象变量或With块变量(错误91)

  10. 10

    在Excel中未设置对象变量或With块变量(错误91)

  11. 11

    在Excel中未设置对象变量或With块变量(错误91)

  12. 12

    VBA中的构造方法-运行时错误91“未设置对象变量”

  13. 13

    Excel VBA运行时错误91对象变量未设置

  14. 14

    运行时错误91:未在Excel 2013中设置对象变量或带有块变量

  15. 15

    for循环的C运行时错误

  16. 16

    运行时无限循环错误

  17. 17

    for循环的C运行时错误

  18. 18

    将对象分配给集合:错误“ 91”:对象变量或未设置带块变量

  19. 19

    VBA错误91:未设置对象变量

  20. 20

    VBA错误91:未设置对象变量

  21. 21

    我收到运行时错误“91”:对象变量或块变量未在工作表上设置。可能没有选择工作表?

  22. 22

    循环和运行时错误中的C ++变量声明

  23. 23

    VBA错误91:未设置对象变量或含块变量(Excel 2013)

  24. 24

    VBA错误91:未设置对象变量或With块变量(Excel 2013)

  25. 25

    未设置对象变量或带块变量(错误91),请协助

  26. 26

    循环内循环的运行时分析

  27. 27

    运行for循环时出现奇怪的运行时错误'424'

  28. 28

    获取运行时错误“91”对象变量 + 整体代码运行状况

  29. 29

    为范围单元的每个循环运行时避免错误?

热门标签

归档