Vider une collention VBA

Hervé

XLDnaute Barbatruc
Bonjour


Pour vider une collection j'utilise la synthaxe : Set datacollection = Nothing

Mais je ne suis pas sur de cette synthaxe, merci de bien vouloir me confirmer ceci.

En vous remerciant pas avance,

Salut
 

MichelXld

XLDnaute Barbatruc
bonjour Hervé

la synthaxe que tu utilises est correcte

néanmoins , dans ce lien , les informations complémentaires fournies par @+Thierry au sujet des collections et des variables objets devraient aussi t'interesser
nottament le message du 25-04-04 17:15

Lien supprimé



je te souhaite une bonne soiree
MichelXld

Message édité par: MichelXld, à: 11/04/2005 17:33
 

_Thierry

XLDnaute Barbatruc
Repose en paix
Bonsoir Hervé, le Forum

Hervé, très bonne question, en fait tout dépend de comment tu déclares/initialises et utilises cet Object Collection...

Je te conseille de lire ce Fil tout d'abord (même si le sujet n'a rien à voir) :

Lien supprimé

Ensuite on va faire une démo de base :

Exemple 1
Option Explicit

Dim MyCollection As Collection

Sub GeneratingCollection()
Dim MyX As Byte
Dim MyItem As Variant
Dim MyString

Set MyCollection = New Collection

   
For MyX = 65 To 90
        MyCollection.Add Chr(MyX), CStr(MyX)
   
Next

   
For Each MyItem In MyCollection
        MyString = MyString & MyItem & vbCrLf
   
Next

MsgBox MyString
End Sub

Dans cette Démo pas de souci... mais maintenant on corse !!

Exemple 2
Option Explicit

Dim MyCollection As Collection

Sub GeneratingCollection()
Dim MyX As Byte

Set MyCollection = New Collection

   
For MyX = 65 To 90
        MyCollection.Add Chr(MyX), CStr(MyX)
   
Next

TheNextMacro
End Sub

Sub TheNextMacro()
Dim MyItem As Variant
Dim MyString

   
For Each MyItem In MyCollection
        MyString = MyString & MyItem & vbCrLf
   
Next
MsgBox MyString
End Sub


Et donc pour Finir, avec la Vidange !!!

Exemple 2
Option Explicit

Dim MyCollection As Collection

Sub GeneratingCollection()
Dim MyX As Byte

Set MyCollection = New Collection

   
For MyX = 65 To 90
        MyCollection.Add Chr(MyX), CStr(MyX)
   
Next

Set MyCollection = Nothing
TheNextMacro
End Sub

Sub TheNextMacro()
Dim MyItem As Variant
Dim MyString

   
For Each MyItem In MyCollection
        MyString = MyString & MyItem & vbCrLf
   
Next
MsgBox MyString
End Sub

Et évidemment ce dernièr exemple plante de la même manière que si le Dim de MyCollection n'était pas niveau Module mais inclus dans la Sub 'GeneratingCollection', donc le Set = Nothing a bien vidé MyCollection...

Bonne Soirée
@+Thierry
 

_Thierry

XLDnaute Barbatruc
Repose en paix
Bonsoir mon cher Michel,

Désolé pas vu, entre toute la mise en page de mes Exemples de Collections !!!

Mais sinon oui merci pour te souvenir de mon travail de recherche dans ce Fameux Fil 84789 !!!

Et sinon démonstration par l'exemple ici maintenant !

Bonne Soirée
@+Thierry
 

Hervé

XLDnaute Barbatruc
Re a vous tous , Ô forum (j'en fait trop là)


Désolé pour cette réponse tardive, mais il m'a fallut du temps pour digérer ce fil.

Petite question, tout de même :

Je fais une synthèse succint de ce que j'ai compris, vous me mettez une baffe si je dis une bétise :

Dim MyCollection As Collection ==> on déclare la variable comme collection

Set MyCollection = New Collection==>on crée l'objet Mycollection

Par contre je n'ai pas compris pourquoi nous ne pourrions pas utiliser dim mycollection as new collection.

j'ai noté à travers la richesse du fil de thierry deux points pour lequelle une 'vulgarisation' me serait fort utile :

'par cette méthode (le dim.... as new collection) 'Auto-Instancing' l'objet 'MyCollection' n'est pas créé par la Déclaration Dim. L'objet est généré.'

'De plus il dit qu'à aucun moment on ne pourra déterminer si cette Variable est en fait vide ou non !
En d'autres termes l'instruction 'New' agit plus comme un ordre de compilation et pas une instruction 'd'action' pour VBA.'

Voilà, si vous pouviez m'expliquer ce que engendre le 'dim ... as new collection' comme problème avenir, et me décrypter ces deux affirmations, je me coucherais moins bête (ce qui ne devrait, convenons-en, ne pas paraitre trop difficile).

au plaisir de vous lire

Salut
 

pat1545.

XLDnaute Accro
Salut _Thierry, le forum

suis pas spécialiste des collections mais ce petit code (qui me sert tous les jours) est basé sur une collection et largement inspiré d'un code de Frederic SIGONNEAU:

Option Explicit

Sub ValUniquesACote() ' PlageSrc As Range, CellDest As Range)
'Extrait les valeurs uniques d'une colonne et les renvoie
'dans une autre, à partir de CellDest tiré d'un code de F. Signonneau (pense-je)
Dim Arr1, Elt, Arr2(), Coll As New Collection, i As Integer
Arr1 = Selection.Value
Dim Colo
Dim line
Dim err
Colo = Selection.Column
line = Selection.Row
For Each Elt In Arr1
On Error Resume Next
Coll.Add Elt, CStr(Elt)
If err.Number = 0 Then
ReDim Preserve Arr2(1 To Coll.Count)
Arr2(Coll.Count) = Elt
End If
On Error GoTo 0
Next
For i = 1 To Coll.Count
If IsEmpty(Cells(line, Colo + 1)) Then
Cells(line + i, Colo + 1).Value = Coll.Item(i)
Else
MsgBox ('cellule voisine non vide')
MsgBox Coll.Item(i)
End If
Next
Application.Transpose (Arr2)
End Sub

Sub MenuCell()
Dim Ctrl
For Each Ctrl In Application.CommandBars('Cell').Controls
Ctrl.Enabled = True
Next
With Application.CommandBars('Cell').Controls.Add(msoControlButton)
.Caption = 'Unique à droite'
.BeginGroup = True
.FaceId = 252
.OnAction = 'ValUniquesACote'
End With
End Sub


Sub Efface_ClicDroit()
On Error Resume Next
Application.CommandBars('Cell').Controls('Unique à droite').Delete
End Sub
 

galopin01

XLDnaute Occasionnel
Bonjour Hervé, le forum,
Sur le plan du résultat, il n'y a pas de différence entre :
Dim X as Collection
Set X = New Collection
et :
Dim X as New Collection

C'est juste une question de forme, la première approche étant peut-être plus pédagogique : Avec Set la création est explicite.

dans l'exemple de Pat1545
Dim X as New Collection
X.Add ... 'La création est implicite

A+
 

_Thierry

XLDnaute Barbatruc
Repose en paix
Bonjour Hervé, Roger, Pat

Je suis ultra à la bourre ce matin avant de partir au taff; mais ce que vous écrivez montre bien que vous n'avez pas lu le Fil 84789 jusqu'au bout !!! (Je sais c'est long, mais c'est moins long de lire que d'écrire !)

Bonne Journée
@+Thierry
 

galopin01

XLDnaute Occasionnel
Oui,
J'étais bien conscient de tenter un peu le ZOP mais...
Dans mes modestes applications je n'ai encore jamais constaté l'empilement d'une instance sur l'autre entre 2 appels de procédure. Ce qui me fait expliquer la chose de cette manière.
Et dans l'un ou l'autre cas, ça n'empêche pas le 'vidage' de l'instance me semble-t-il ? Et re-ZOP ?
Bon j'arrête... (demain !)
Ceci dit le 'Set' me semble effectivement une saine habitude de programmation, ne serait ce qu'au niveau du décodage !
Merci _Thierry de rappeler tous ces fondamentaux.

A+
 

Ti_

Nous a quitté
Repose en paix
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.
 

_Thierry

XLDnaute Barbatruc
Repose en paix
Bonjour Ti, re Roger, Pat, Hervé et le Forum

Hihihi, et bien Ti, en général, tu n'écris pas de longs posts, mais quand 'Tu Ti' mets... c'est loin d'être pour ne rien dire !!!

Merci à Ti, Merci à Toi !

Bon Après midi
@+Thierry
 
A

arnaudmuse

Guest
creation clasuuer

slt je souhaiterai créer un classeur en vba.j'utilise Dim mavariable as Workbook et apres dans mon code je fait Set mavariable = new Workbook .mais quand je regarde dans le tableau de variable la valuer de mavariable est aegale a nothing pourtant je l'ai instantier non?
Merci
 

ChTi160

XLDnaute Barbatruc
Re:creation clasuuer

Salut arnaudmuse
Bonjour le Forum
tu tentes d'utiliser une procèdure qui ne correspond pas
pour ajouter un nouveau Classeur la procèdure est
Workbooks.Add
ex Tu Crees un Classeur et tu le Nommes Toto
Sub newClasseur()
Dim Wkb As Workbook
Workbooks.Add
Set Wkb = ActiveWorkbook
Wkb.SaveAs 'Toto'
End Sub
je te conseille d'Utiliser l'enregistreur de Macro de la Barre Visual Basic
très pratique pour Apprendre
Amicalement
Jean Marie

Message édité par: ChTi160, à: 02/05/2005 08:39
 

Discussions similaires

Réponses
13
Affichages
213
Réponses
45
Affichages
1 K

Statistiques des forums

Discussions
312 106
Messages
2 085 351
Membres
102 871
dernier inscrit
Maïmanko