Salut à tous.
Je me souviens de cette discussion sur les collections : faut-il déclarer une collection ... as Collection ou As New Collection.
Moi, je pratique l'un et l'autre, selon les cas.
Tout d'abord, autant que possible, j'évite les déclarations globales de variables. Il est souvent plus simple de déclarer tout un tas de variables globales, mais cette façon de faire est aussi souvent génératrice d'erreurs difficiles à repérer, notamment quand il s'agit, comme dans la question de ce fil, de réinitialiser une variable globale.
Comment faire pour travailler avec des collections qui ne soient pas globales ? eh bien chaque fois qu'on le peut, il est bien plus élégant d'écrire une fonction qui renvoie une collection, du genre :
Function ListeElements(Plage As Range) As Collection
Dim Col As New Collection, Cel As Range
For Each Cel in Plage
Col.Add Cel
Next Cel
Set ListeElements = Col
End Function
Ensuite, on peut, dans la procédure qui utilise la collection ci-dessus, déclarer une variable ... As Collection (sans le New)
ex :
Sub MetEnForme()
Dim Col as Collection, Plage As Range
Set Plage = Feuil1.Range('MaListe')
Set Col = ListeElements(Plage)
etc.
End Sub
Je procède ainsi dans tous mes programmes qui travaillent sur des listes par collection (et par simple arrays aussi d'ailleurs). Mes collections sont déclarées localement, plus aucun risque d'oubli de les réinitialiser et de plus je ne laisse 'aucune trace' de mon passage. Cette dernière remarque peut vous faire sourire, mais personnellement j'aime bien savoir que 'le ménage est fait' quand je quitte une procédure, ou quand je ferme un formulaire et dans ce sens, mes programmes sont beaucoup mieux rangés que mon bureau (arf).
Concernant le As New, VB ajoute quelques instructions pour vérifier que la variable est toujours instanciée, le temps mis pour cette vérification est négligeable dans le cadre de ma fonction, ce n'est pas plus long en tout cas que si j'avais rajouté la ligne :
Set Col = New Collection
En fait VB aurait ajouté plus d'instructions si j'avais dû écrire Set Col = Nothing, mais je n'ai pas besoin de ça puisque la variable Col disparaît dès la sortie de ma fonction.
La différence entre les deux déclarations c'est qu'une variable déclarée As New étant toujours instanciée, pour la vider il suffit d'écrire Set Col = Nothing, et on peut recommencer à l'alimenter immédiatement par un Col.Add, alors que si on l'avait déclarée As Collection, si on écrit Set Col = Nothing, la variable n'existe vraiment plus, il faudra refaire un Set Col = New Collection avant de la réutiliser. Cette deuxième façon de faire est, me semble-t-il, préférable dans le cas d'une variable globale.
Notez bien, c'est le plus intéressant, que de toute façon même si votre Collection est une variable globale, ou si vous la réutilisez pour alimenter plusieurs collections dans une procédure, entre deux appels à la fonction ListeElements, vous n'avez nul besoin de la réinitialiser. C'est ainsi qu'il est très simple et très rapide d'initialiser la liste d'un combobox qui évolue en permanence en fonction des choix faits dans une autre liste par exemple.
On pourrait ainsi écrire :
Sub MetEnForme()
Dim Col as Collection, Plage As Range
Set Plage = Feuil1.Range('MaListe')
Set Col = ListeElements(Plage)
'utilisation de la collection
'...
Set Plage = Feuil1.Range('AutreListe')
Set Col = ListeElements(Plage)
'utilisation de la deuxième collection
'...
End Sub
Pour finir, un conseil qui n'a rien à voir avec ce qui précède (enfin si, un peu) : une procédure ne devrait pas dépasser 10 ou 20 lignes maximum, ça vous évite les Goto et autres joyeusetés (et même les Gosub comme j'en ai vus sur ce forum la semaine dernière !) et c'est 100 000 fois plus simple à maintenir, quand on doit reprendre le programme 1 an plus tard et qu'il nous était totalement sorti de l'esprit.