将对象设置为"Nothing"有什么好处

urd*_*boy 7 excel vba excel-vba

我注意到有些人会Set Object = Nothing在结账程序中使用.我能够找到为什么这对Access的实例有用,但是在为Excel执行此操作时没有答案令人满意,那么, 将对象设置为Nothing的好处是什么?

我把它添加到我的代码中作为例子来支持这个问题,但这只是浪费空间吗?如果这是一个好习惯,为什么?

至于代码都没有问题, Set = Nothing.我从具有我们不需要的过多列的系统导出中获取数据.为了减少复制/粘贴迭代的数量,我使用union来获取所有范围,但两个除外.需要切换最后两列的顺序,这就是我被迫分别复制/粘贴它们的原因.

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
Run Code Online (Sandbox Code Playgroud)

Mat*_*don 12

如果这是托管的.NET代码(垃圾收集),你必须Release访问你访问过的每一个COM对象,以免主机进程(EXCEL.EXE)可能在后台运行,消耗内存而无法访问彻底拆掉

但这是VBA代码(它是引用计数的),而且VBA代码使用主机应用程序控制的对象 - 这些对象将在主机应用程序关闭时死亡,并且当发生这种情况时,VBA执行上下文早已消失.

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


在某些特定情况下,当您处理第三方API /类型库时,对象可能无法完全清理.例如,您可能正在创建一个Access.Application实例,并且在Excel退出后发现"幽灵"ACCESS.EXE进程在任务管理器中保持打开状态:这表示您在某处某处泄漏了对象引用,并且Set ... = Nothing可以帮助防止这种情况发生.

但是,我不建议系统地将所有对象引用归零.只有这样做才会导致问题.即使这样,它也会成为一两个物体,拖拽一切,而不是所有物体.如果ACCESS.EXE正常关闭,则没有理由使用此类指令使代码混乱.

避免在全局状态下存储对象引用也有帮助.如果一切都是本地的,理论上所有涉及的对象一旦局部范围退出就会被销毁.

  • @QHarr我不在VBA中做IE的东西,但是如果我这样做,我可能会将实例括在一个`With`块中,例如`With New InternetExplorer`或者类名是什么:当`With`块时拥有该实例,当达到"End With"时,该对象将死亡. (4认同)
  • 这是关于“With”块的非常好的注释 (2认同)