在Excel VBA中,如何测试Excel.Range对象变量是否丢失其引用而不会引发运行时错误424 ..?

spi*_*tor 9 excel vba

在Excel VBA中,如果变量是Excel.Range,并且删除了它引用的范围,则会丢失其引用.任何访问该变量的尝试都会导致Runtime Error 424: object required.

Dim rng As Range
Set rng = Sheet1Range("A1")
Sheet1.Rows(1).Delete       'Range has been deleted.
Debug.Print rng.Address()   'Any access attempt now raises runtime error 424.
Run Code Online (Sandbox Code Playgroud)

有没有办法测试这种"丢失参考"状态没有错误处理程序..?

测试Nothing,Vartype()和Typename()都没有用,因为变量仍然是一个Range.我完全阅读了对象浏览器中的所有Excel.Application,但一无所获.也许有一些我忽略的东西......?比如史前版本的Excel中那些奇怪的残余函数之一,比如ExecuteExcel4Macro()..?

我在谷歌搜索了这个问题的答案,但没有找到任何帮助.

编辑:

有些人问我为什么要避免错误处理程序.这是我正常的编程理念,原因有两个:

  • 我确实认识到有时错误处理程序是最快捷的方式,或者唯一的方法.但这不是最优雅的方式.看起来好吧,对我来说很糟糕.这就像白色洗涤栅栏和绘制我的猫的肖像之间的区别.= - )
  • 我避免错误处理程序的另一个原因是教育.很多时候,在寻找替代方案时,我会发现以前从未知道的属性,程序,对象甚至整个库.在这样做的过程中,我找到了更多的装甲来防御我的代码.

Rya*_*dry 2

这是一种应该能够解决该问题的方法,尽管它不是检查它是否被自行删除的好解决方案。我认为错误处理可能是最好的方法。

\n\n
Sub Example()\n    Dim foo1 As Range\n    Dim foo2 As Range\n    Dim foo3 As Range\n    Dim numberOfCells As Long\n\n    Set foo1 = Sheet1.Range("A1")\n    Set foo2 = foo1.Offset(1, 0) \'Get the next row, ensure this cell exists after row deletion!\n    Set foo3 = Union(foo1, foo2)\n    numberOfCells = foo3.Cells.Count\n\n    Debug.Print "There are " & numberOfCells & " cells before deletion"\n    Sheet1.Rows(1).Delete\n\n    Debug.Print "There are now " & foo3.Cells.Count & " cells"\n\n    If foo3.Cells.Count <> numberOfCells Then\n        Debug.Print "One of the cells was deleted!"\n    Else\n        Debug.Print "All cells still exist"\n    End If\nEnd Sub\n
Run Code Online (Sandbox Code Playgroud)\n\n

另外,这是一种更加面向功能的方法,这可能是添加到代码库中稍微更好的方法。同样,这并不理想,但它不应该需要错误处理程序。

\n\n
Private getRange As Range\n\nSub Example()\n    Dim foo         As Range\n    Dim cellCount   As Long\n\n    Set foo = Sheet1.Range("A1")\n    cellCount = GetCellCountInUnion(foo)\n    Sheet1.Rows(1).Delete\n\n    If Not cellCount = getRange.Cells.Count Then\n        Debug.Print "The cell was removed!"\n    Else\n        Debug.Print "The cell still exists!"\n    End If\n\nEnd Sub\n\nPrivate Function GetCellCountInUnion(MyRange As Range) As Long\n    Set getRange = Union(MyRange, MyRange.Parent.Range("A50000")) \xe2\x80\x98second cell in union is just a cell that should exist\n    GetCellCountInUnion = getRange.Cells.Count\nEnd Function\n
Run Code Online (Sandbox Code Playgroud)\n