web-dev-qa-db-fra.com

Comment détruire un objet

Il paraît que Set Object = Nothing n'a pas détruit l'objet Fs dans ce code:

Sub Test2()
    Dim Fs As New FileSystemObject
    Set Fs = Nothing
    MsgBox Fs.Drives.Count ' this line works
End Sub

La dernière ligne fonctionne sans erreur!. cela signifie que Fs L'objet existe toujours, non?.

Alors, comment détruire cet objet Fs.

15
Fadi

Une autre façon de garantir la destruction appropriée d'un objet est de céder sa référence d'objet à un bloc With (c'est-à-dire de ne pas déclarer de variable locale):

Sub Test()
    With New FileSystemObject
        MsgBox .Drives.Count
    End With
End Sub

L'objet n'existe que dans le bloc With et lorsque l'exécution atteint le End With jeton, si vous l'essayez avec un module de classe personnalisé, vous remarquerez que la classe 'Class_Terminate le gestionnaire s'exécute, confirmant efficacement la destruction appropriée de l'objet.

En ce qui concerne la As New bizarrerie, comme cela a déjà été expliqué , si vous avez l'intention de définir la référence d'objet sur Nothing dans cette portée, ne la déclarez pas avec As New, car VBA sera définissez la référence d'objet sur Nothing, mais créera également avec plaisir ("utilement") une nouvelle instance pour vous dès que vous la re-référencerez encore une fois, ne serait-ce que pour vérifier que l'objet Is Nothing.

Note latérale, ce comportement contre-intuitif (ennuyeux) est précisément ce qui se cache derrière le raisonnement pour Rubberduck 's La variable objet est auto-assignée inspection du code:

RD website's inspection results

(Remarque: si vous avez du code que vous souhaitez inspecter, sachez qu'il s'exécute beaucoup plus rapidement dans le VBE réel que sur le site Web)

(si ce n'était pas déjà clair: je suis fortement impliqué dans le projet Rubberduck)

16
Mathieu Guindon

cela doit avoir à voir avec le modèle "déclarer et instancier", le plus souvent traité comme un modèle "à éviter"

si vous les divisez, vous obtenez Nothing après l'avoir défini sur:

Sub Test2()
    Dim Fs As FileSystemObject
    Set Fs = New FileSystemObject
    Set Fs = Nothing
    MsgBox Fs.Drives.Count ' this line DOESN'T work
End Sub
17
user3598756

Ce code modifié semble bien fonctionner. Semble une nuance avec le dim/new sur la même ligne. Espérons que quelqu'un d'autre puisse donner une meilleure idée du raisonnement.

Comme d'autres l'ont commenté, s'il s'agit d'un faible dans le sous-marin, il sera collecté une fois le sous-programme terminé.

Sub Test2()
    Dim Fs As FileSystemObject
    Set Fs = New FileSystemObject
    Set Fs = Nothing
End Sub
11
Zerk