Quand une variable VBA Excel doit-elle être tuée ou réglée à rien?

je me suis enseigné Excel VBA au cours des deux dernières années, et j'ai l'idée qu'il est parfois approprié de disposer de variables à la fin d'un segment de code. Par exemple, je l'ai vu fait dans ce bit adapté de le code de Ron De Bruin pour le transfert D'Excel au 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

j'ai fait quelques recherches sur ce et trouvé très peu au-delà de comment le faire, et dans un post de forum une déclaration qu'aucun local les variables doivent être effacées , puisqu'elles cessent d'exister à End Sub . Je suppose, basé sur le code ci-dessus, que ce n'est peut-être pas vrai à End Function , ou dans d'autres circonstances que je n'ai pas rencontré.

donc ma question se résume à ceci:

  • est-ce qu'il y a quelque part sur le web qui explique quand et pourquoi pour le nettoyage des variables, et je ne l'ai tout simplement pas trouvé?

Et si non quelqu'un peut ici, veuillez expliquer...

  • quand le nettoyage variable pour Excel VBA est-il nécessaire et quand il ne l'est pas?
  • et plus spécifiquement... Existe-t-il des utilisations variables spécifiques (variables publiques? Variables définies par la fonction?) qui restent chargés en mémoire pour plus que les sous-marins, et donc pourrait causer des problèmes si Je ne nettoie pas après moi-même?
22
demandé sur Community 2013-09-27 00:44:12

3 réponses

VB6 / VBA utilise une approche déterministe pour dénouer les objets. Chaque objet stocke le nombre de références à elle-même. Lorsque le nombre atteint zéro, l'objet est détruit.

les variables D'objet sont garanties pour être nettoyées (paramétrées à Nothing ) lorsqu'elles sortent du champ d'application, ceci décrémente les compteurs de référence dans leurs objets respectifs. Aucune action manuelle requise.

il n'y a que deux cas où vous voulez un nettoyage explicite:

  1. quand vous voulez qu'un objet soit détruit avant que sa variable ne soit hors de portée (par exemple, votre procédure va prendre beaucoup de temps à exécuter, et l'objet détient une ressource, donc vous voulez détruire l'objet dès que possible pour libérer la ressource).

  2. lorsque vous avez une référence circulaire entre deux ou plusieurs objets.

    si objectA contient une référence à objectB , et objectB stocke une référence à objectA , les deux objets ne seront jamais détruits à moins que vous ne freinez la chaîne en mettant explicitement objectA.ReferenceToB = Nothing ou objectB.ReferenceToA = Nothing .

le code que vous montrez est erroné. Pas de nettoyage manuel est nécessaire. Il est même nocif de faire un nettoyage manuel, car il vous donne un faux sens du code plus correct .

si vous avez une variable à un niveau de classe, il sera être nettoyé / détruit lorsque l'instance de classe est détruite. Vous pouvez le détruire plus tôt si vous le souhaitez (voir la rubrique 1. ).

si vous avez une variable au niveau d'un module, elle sera nettoyée/détruite lorsque votre programme sortira (ou, dans le cas de VBA, lorsque le projet VBA sera réinitialisé). Vous pouvez le détruire plus tôt si vous le souhaitez (voir la rubrique 1. ).

le niveau d'accès D'une variable (publique ou privée) n'a aucune incidence sur sa durée de vie.

36
répondu GSerg 2017-05-23 12:03:05

VBA utilise un collecteur d'ordures qui est mis en œuvre par comptage de référence .

il peut y avoir plusieurs références à un objet donné (par exemple, Dim aw = ActiveWorkbook crée une nouvelle référence à un classeur actif), de sorte que le ramasseur d'ordures ne nettoie un objet que lorsqu'il est clair qu'il n'y a pas d'autres références. Le réglage à Zéro est une façon explicite de décrémenter le compte de référence. Le compte est implicitement décrémenté quand vous sortez portée.

à proprement parler, moderne versions d'Excel (2010+) pour Rien n'est pas nécessaire, mais il y avait des problèmes avec les anciennes versions d'Excel (pour lequel la solution a été de définir explicitement)

3
répondu SheetJS 2013-09-26 20:58:38

j'ai au moins une situation où les données ne sont pas automatiquement nettoyées, ce qui pourrait éventuellement conduire à des erreurs" hors de mémoire". Dans un format D'utilisateur j'ai eu:

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

lorsque UserForm a été détruit (après Unload Me ) la mémoire allouée pour les données chargées dans le mainPicture n'était pas en cours de suppression. J'ai dû ajouter un

mainPicture = Nothing

en cas de résiliation.

0
répondu Tomasz 2018-09-28 13:06:29