在过去的两年里,我一直在教自己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
可能不正确,或者在其他情况下我没有遇到过。
所以我的问题归结为:
如果没有,请有人在这里解释......
答案 0 :(得分:44)
VB6 / VBA使用确定性方法来处理令人讨厌的对象。每个对象存储自身的引用数。当数字达到零时,对象将被销毁。
当对象变量超出范围时,它们保证被清除(设置为Nothing
),这会减少各自对象中的引用计数器。无需手动操作。
只有两种情况需要明确清理:
如果希望在变量超出范围之前销毁对象(例如,您的过程将花费很长时间来执行,并且对象拥有资源,那么您希望将对象销毁为尽快释放资源)。
当两个或多个对象之间有循环引用时。
如果objectA
存储对objectB
的引用,而objectB
存储对objectA
的引用,则除非您通过明确设置制动链,否则这两个对象永远不会被销毁objectA.ReferenceToB = Nothing
或objectB.ReferenceToA = Nothing
。
您显示的代码段错误。无需手动清理。进行手动清理甚至是有害的,因为它会为您提供false sense of more correct code。
如果在类级别有变量,则在销毁类实例时将清除/销毁它。如果需要,可以提前销毁它(参见项目1.
)。
如果模块级别有变量,则在程序退出时将清除/销毁该变量(或者,如果是VBA,则重置VBA项目时)。如果需要,可以提前销毁它(参见项目1.
)。
变量的访问级别(公共与私有)不会影响其生命周期。
答案 1 :(得分:3)
VBA使用由reference counting实现的垃圾收集器。
可以有多个对给定对象的引用(例如,Dim aw = ActiveWorkbook
创建对Active Workbook的新引用),因此垃圾收集器只有在清楚没有其他引用时才清理对象。设置为Nothing是递减引用计数的明确方法。退出范围时,计数会隐式递减。
严格地说,在现代Excel版本(2010+)中,设置为Nothing不是必需的,但是旧版本的Excel存在问题(其解决方法是明确设置)
答案 2 :(得分:0)
我至少有一种情况不会自动清理数据,最终将导致“内存不足”错误。 在UserForm中,我有:
Public mainPicture As StdPicture
...
mainPicture = LoadPicture(PAGE_FILE)
在销毁用户窗体(在Unload Me
之后)时,未取消分配为在mainPicture
中加载的数据分配的内存。我必须添加一个明确的
mainPicture = Nothing
在终止事件中。