Подтвердить что ты не робот

Когда переменная Excel VBA должна быть убита или установлена ​​в Nothing?

Я изучаю Excel VBA за последние два года, и у меня есть идея, что иногда уместно распоряжаться переменными в конце сегмента кода. Например, я видел, как это было сделано в этом бите, адаптированном из кода Ron de Bruin для переноса Excel в HTML:

Function SaveContentToHTML (Rng as Range)

        Dim FileForHTMLStorage As Object
        Dim TextStreamOfHTML As Object
        Dim TemporaryFileLocation As String
        Dim TemporaryWorkbook As Workbook

...

        TemporaryWorkbook.Close savechanges:=False
        Kill TemporaryFileLocation
        Set TextStreamOfHTML = Nothing
        Set FileForHTMLStorage = Nothing
        Set TemporaryWorkbook = Nothing

End Function

Я немного поработал над этим и нашел очень мало того, как это сделать, и в одном сообщении на форуме о том, что локальные переменные не нужно очищать, так как они перестают существовать при End Sub. Я предполагаю, что, основываясь на приведенном выше коде, это может быть неверно в End Function или в других обстоятельствах, с которыми я не сталкивался.

Итак, мой вопрос сводится к следующему:

  • Есть ли где-то в Интернете, которые объясняют, когда и почему для очистки переменных, и я просто не нашел его?

И если не может кто-то здесь объяснить, пожалуйста...

  • Когда требуется переменная для Excel VBA, а когда нет?
  • И более конкретно... Используются ли определенные переменные (общедоступные переменные? Функциональные переменные?), Которые дольше сохраняются в памяти чем подводные лодки, и поэтому могут возникнуть проблемы, если я не буду чистить после себя?
4b9b3361

Ответ 1

VB6/VBA использует детерминированный подход к уничтожающим объектам. Каждый объект хранит количество ссылок на себя. Когда число достигает нуля, объект уничтожается.

Объектные переменные гарантированно очищаются (устанавливаются на Nothing), когда они выходят из области действия, это уменьшает счетчики ссылок в их соответствующих объектах. Никаких ручных действий не требуется.

Есть только два случая, когда требуется явная очистка:

  • Если вы хотите, чтобы объект был уничтожен до того, как его переменная выходит из области видимости (например, ваша процедура займет много времени, и объект хранит ресурс, поэтому вы хотите уничтожить объект как как можно скорее освободить ресурс).

  • Если у вас есть круговая ссылка между двумя или более объектами.

    Если objectA хранит ссылки на objectB, а objectB хранит ссылку на objectA, эти два объекта никогда не будут уничтожены, если вы не заблокируете цепочку, явно установив objectA.ReferenceToB = Nothing или objectB.ReferenceToA = Nothing.

Показанный фрагмент кода неверен. Не требуется ручная очистка. Даже ручная очистка даже вредна, поскольку она дает вам ложное чувство более правильного кода.

Если у вас есть переменная на уровне класса, она будет очищена/уничтожена, когда экземпляр класса будет уничтожен. Вы можете уничтожить его раньше, если хотите (см. Пункт 1.).

Если у вас есть переменная на уровне модуля, она будет очищена/уничтожена, когда ваша программа выйдет (или, в случае VBA, когда проект VBA - reset). Вы можете уничтожить его раньше, если хотите (см. Пункт 1.).

Уровень доступа переменной (public vs. private) не влияет на время ее жизни.

Ответ 2

VBA использует сборщик мусора, который реализуется подсчет ссылок.

Может быть несколько ссылок на данный объект (например, Dim aw = ActiveWorkbook создает новую ссылку на Active Workbook), поэтому сборщик мусора очищает объект только тогда, когда становится ясно, что других ссылок нет. Установка в Nothing - это явный способ уменьшения количества ссылок. Граф неявно уменьшается при выходе из области.

Строго говоря, в современных версиях Excel (2010+) параметр Nothing не нужен, но были проблемы со старыми версиями Excel (для которых обходной путь был явно установлен)