将对象设置为“无”的好处是什么

时间:2018-06-27 14:37:20

标签: vba excel-vba excel

我注意到有些人在关闭程序时会使用Set Object = Nothing。我能够找到为什么这对于Access实例很有用,但是在Excel方面却没有令人满意的答案,因此,  将对象设置为Nothing到底有什么好处?

我将其添加到代码中作为支持此问题的示例,但这仅仅是浪费空间吗?如果是好的做法,为什么?

就代码而言,没有没有 Set = Nothing。我正在从具有不需要的过多列的系统导出中获取数据。为了减少复制/粘贴迭代的次数,我用一个并集(除两个外)来抓取所有范围。最后两列的顺序需要切换,这就是为什么我被迫分别复制/粘贴它们的原因。

With CurrentBook.ActiveSheet

    Dim LRow2 As Long
    LRow2 = .Range("BG" & .Rows.Count).End(xlUp).Row

    Dim Range1 As Range: Set Range1 = .Range("A2:C" & LRow2)
    Dim Range2 As Range: Set Range2 = .Range("F2:F" & LRow2)
    Dim Range3 As Range: Set Range3 = .Range("H2:H" & LRow2)
    Dim Range4 As Range: Set Range4 = .Range("M2:M" & LRow2)
    Dim Range5 As Range: Set Range5 = .Range("P2:P" & LRow2)
    Dim Range6 As Range: Set Range6 = .Range("S2:S" & LRow2)
    Dim Range7 As Range: Set Range7 = .Range("V2:V" & LRow2)
    Dim Range8 As Range: Set Range8 = .Range("X2:X" & LRow2)
    Dim Range9 As Range: Set Range9 = .Range("AD2:AD" & LRow2)
    Dim Range10 As Range: Set Range10 = .Range("AR2:AX" & LRow2)
    Dim Range11 As Range: Set Range11 = .Range("AY2:AY" & LRow2)
    Dim Range12 As Range: Set Range12 = .Range("AZ2:AZ" & LRow2)

End With

Dim CopyRange As Range: Set CopyRange = Union(Range1, Range2, Range3, Range4, Range5, Range6, Range7, Range8, Range9, Range10)
CopyRange.Copy
ws.Range("A2").PasteSpecial xlPasteValues

    Range12.Copy
    ws.Range("S2").PasteSpecial xlPasteValues

        Range11.Copy
        ws.Range("T2").PasteSpecial xlPasteValues

'''''''''''''''
''''Closing''''
'''''''''''''''

Closing:
CurrentBook.Close False
ws.Range("A1").Select

Application.ScreenUpdating = True
Application.DisplayAlerts = True

Set MyFile = Nothing: Set ws = Nothing: Set CurrentBook = Nothing
Set Range1 = Nothing: Set Range2 = Nothing: Set Range3 = Nothing: Set Range4 = Nothing: Set Range5 = Nothing
Set Range6 = Nothing: Set Range7 = Nothing: Set Range8 = Nothing: Set Range9 = Nothing:
Set Range10 = Nothing: Set Range11 = Nothing: Set Range12 = Nothing
Set CopyRange = Nothing

Exit Sub

1 个答案:

答案 0 :(得分:12)

如果这是受托管的.NET代码(是垃圾收集的),则您必须Release曾经访问过的每个COM对象,以免宿主进程(EXCEL。 EXE)可能会继续在后台运行,从而消耗内存并且无法完全拆除。

但这是VBA代码(引用计数为 ),此外,VBA代码还使用宿主应用程序控制的对象-这些对象将在宿主应用程序关闭时以及在发生这种情况时消失VBA执行上下文早已消失。

换句话说,所有这些Set ... = Nothing指令都是完全多余的。


在某些特定情况下,当您使用第三方API /类型库时,对象可能无法完全清除。例如,您可能正在创建一个Access.Application实例,并发现在Excel退出后,任务管理器中的“ ghost” ACCESS.EXE进程仍然保持打开状态:这表明​​您在某种程度上泄漏了对象引用,和Set ... = Nothing可以帮助防止这种情况。

但是,我不建议像这样系统地使所有对象引用无效。仅当 not 这样做时才引起问题。即使到那时,也将是一个或两个对象将所有内容拖下,而不是全部拖动。如果ACCESS.EXE正常关闭,则没有理由按照此类说明来弄乱您的代码。

避免以全局状态存储对象引用也有帮助。如果一切都是本地的,理论上讲,只要本地范围退出,所有涉及的对象都会被销毁。