In Excel VBA, if a variable is Excel.Range, and the range it refers to is deleted, it loses its reference. Any attempt to access the variable results in 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.
Is there a way to test for this state of "lost reference" without an error handler..?
Testing Nothing
, Vartype(), and Typename() were all not useful because the variable is still a Range. I literally read through all of Excel.Application in the Object browser, but found nothing. Perhaps there's something I'm overlooking..? Such as one of those strange vestigial functions from prehistoric versions of Excel, like ExecuteExcel4Macro()..?
I've searched Google for the answer to this question, but didn't find anything helpful.
EDIT:
Some have asked why I'm trying to avoid an error handler. This is my normal programming philosophy for a couple reasons:
To check if a cell is empty you can use VBA's ISEMPTY function. In this function, you need to use the range object to specify the cell that you want to check, and it returns true if that cell is empty, otherwise false. You can use a message box or use a cell to get the result.
In rare cases, this error occurs when you have a valid object but are attempting to perform an invalid action on the object. For example, you may receive this error if you try to assign a value to a read-only property. Check the object's documentation and make sure the action you are trying to perform is valid.
The error is caused by a function being called on a reference you've either misspelled, or have not declared. The solution is to ensure you have all the appropriate references declared within your code.
Here's an approach that should be able to workaround the issue, although it isn't a great solution for checking if it was removed by itself. I think error handling is probably your best approach.
Sub Example()
Dim foo1 As Range
Dim foo2 As Range
Dim foo3 As Range
Dim numberOfCells As Long
Set foo1 = Sheet1.Range("A1")
Set foo2 = foo1.Offset(1, 0) 'Get the next row, ensure this cell exists after row deletion!
Set foo3 = Union(foo1, foo2)
numberOfCells = foo3.Cells.Count
Debug.Print "There are " & numberOfCells & " cells before deletion"
Sheet1.Rows(1).Delete
Debug.Print "There are now " & foo3.Cells.Count & " cells"
If foo3.Cells.Count <> numberOfCells Then
Debug.Print "One of the cells was deleted!"
Else
Debug.Print "All cells still exist"
End If
End Sub
Also, here is a more function oriented approach which may be a slightly better approach to add to your codebase. Again, not ideal, but it should not require an error handler.
Private getRange As Range
Sub Example()
Dim foo As Range
Dim cellCount As Long
Set foo = Sheet1.Range("A1")
cellCount = GetCellCountInUnion(foo)
Sheet1.Rows(1).Delete
If Not cellCount = getRange.Cells.Count Then
Debug.Print "The cell was removed!"
Else
Debug.Print "The cell still exists!"
End If
End Sub
Private Function GetCellCountInUnion(MyRange As Range) As Long
Set getRange = Union(MyRange, MyRange.Parent.Range("A50000")) ‘second cell in union is just a cell that should exist
GetCellCountInUnion = getRange.Cells.Count
End Function
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With