什么时候应该杀死Excel VBA变量或将其设置为Nothing?

问题描述 投票:28回答:3

在过去的两年里,我一直在教自己Excel VBA,我认为有时候在代码段的末尾处理变量是合适的。例如,我已经看到它在Ron de Bruin's code for transferring Excel to 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

我已经做了一些搜索,并发现除了如何做之外,并在一个论坛发布a statement that no local variables need to be cleared,因为它们不再存在于End Sub。我猜测,基于上面的代码,在End Function可能不是真的,或者在我没有遇到的其他情况下。

所以我的问题归结为:

  • 网上有什么地方可以解释变量清理的时间和原因,而我还没有找到它?

如果没有,请有人在这里解释......

  • 何时需要对Excel VBA进行变量清理,何时不进行?
  • 更具体地说......是否存在特定的变量用法(公共变量?函数定义的变量?),它们在内存中加载的时间比sub要长,如果我不自行清理,可能会造成麻烦?
variables excel-vba vba excel
3个回答
44
投票

VB6 / VBA使用确定性方法来处理令人讨厌的对象。每个对象存储自身的引用数。当数字达到零时,对象将被销毁。

保证在超出范围时清理对象变量(设置为Nothing),这会减少各自对象中的引用计数器。无需手动操作。

只有两种情况需要显式清理:

  1. 当你想要一个对象在它的变量超出范围之前被销毁时(例如,你的过程将花费很长时间来执行,并且该对象拥有一个资源,所以你想要尽快销毁该对象以释放它资源)。
  2. 当两个或多个对象之间有循环引用时。 如果objectA存储对objectB的引用,并且objectB存储对objectA的引用,则除非通过明确设置objectA.ReferenceToB = NothingobjectB.ReferenceToA = Nothing来制动链,否则这两个对象永远不会被破坏。

您显示的代码段是错误的。无需手动清理。手动清理甚至是有害的,因为它会给你一个false sense of more correct code

如果在类级别有变量,则在类实例被销毁时将清除/销毁它。如果需要,可以提前销毁它(参见1.项)。

如果模块级别有变量,则在程序退出时将清除/销毁该变量(或者,如果是VBA,则重置VBA项目时)。如果需要,可以提前销毁它(参见1.项)。

变量的访问级别(公共与私有)不会影响其生命周期。


3
投票

VBA使用由reference counting实现的垃圾收集器。

可以有多个对给定对象的引用(例如,Dim aw = ActiveWorkbook创建对Active Workbook的新引用),因此垃圾收集器仅在清除没有其他引用时清除对象。设置为Nothing是递减引用计数的明确方法。退出范围时,计数会隐式递减。

严格地说,在现代Excel版本(2010+)中,设置为Nothing不是必需的,但是旧版本的Excel存在问题(其解决方法是明确设置)


0
投票

我至少有一种情况,数据不会自动清理,最终会导致“内存不足”错误。在UserForm我有:

Public mainPicture As StdPicture
...
mainPicture = LoadPicture(PAGE_FILE)

当UserForm被销毁时(在Unload Me之后),为mainPicture中加载的数据分配的内存未被解除分配。我不得不添加一个明确的

mainPicture = Nothing

在终止事件中。

© www.soinside.com 2019 - 2024. All rights reserved.