В Excel VBA как я могу проверить, что объектная переменная Excel.Range теряет свою ссылку, не вызывая ошибку времени выполнения 424 ..? - PullRequest
0 голосов
/ 28 января 2019

В 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.

. Есть ли способ проверить это состояние "потерянной ссылки" без обработчика ошибок ..?

Проверка Nothing, Vartype () и Typename () были бесполезны, потому что переменная все еще является Range.Я буквально прочитал все Excel.Application в браузере объектов, но ничего не нашел.Возможно, я что-то упускаю из виду ...?Например, одна из странных рудиментарных функций из доисторических версий Excel, например, ExecuteExcel4Macro () ..?

Я искал в Google ответ на этот вопрос, но не нашел ничего полезного.

EDIT:

Некоторые спрашивают, почему я пытаюсь избежать обработчика ошибок.Это моя нормальная философия программирования по нескольким причинам:

  • Я признаю, что иногда обработчик ошибок является самым быстрым или единственным способом.Но это не самый элегантный способ.Просто кажется, ну ... грубо для меня.Это как разница между белым мытьем заборчика и написанием портрета моей кошки.= -)
  • Другая причина, по которой я избегаю обработчиков ошибок, - это образование.Много раз, когда я искал альтернативу, я обнаруживал свойства, процедуры, объекты или даже целые библиотеки, которых я никогда не знал раньше.И при этом я нахожу больше доспехов для пуленепробиваемости моего кода.

1 Ответ

0 голосов
/ 29 января 2019

Вот подход, который должен быть в состоянии обойти проблему, хотя он не является отличным решением для проверки, был ли он удален сам по себе.Я думаю, что обработка ошибок - это, вероятно, ваш лучший подход.

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

Кроме того, здесь есть более функционально-ориентированный подход, который может быть немного лучшим подходом для добавления в вашу кодовую базу.Опять же, не идеально, но для этого не требуется обработчик ошибок.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...