Aide compréhension syntaxe VBA
Bonjour,
Question pour une débutante:
Je viens de lire dans un cours de VBA qu'un objet Excel est l'instance d'une classe.
Par exemple, pour manipuler une cellule dans un classeur, VBA utilise l'instance de la classe Range. Si je comprends bien, l'objet cellule est un objet crée par la classe Range?
Pourtant, lorsque je clique sur ce lien:https://docs.microsoft.com/fr-fr/office/vba/api/overview/excel/object-model, puis dans la liste de gauche, lorsque je clique sur "Range", j'ai au choix soit des propriétés, soit des méthodes...(mais pas d'objets...). Et, dans la liste des propriétés, il y a "Cells", est-ce que cela veut dire que lorsque j'écris "Range.cells" dans mon code, je crée un objet cellule (alors que dans la documentation c'est annoncé comme une propriété...)?
Merci d'avance pour votre éclaircissement
Bonjour,
Hum... Selon mon avis, tu peux bien zapper ce genre de question qui ne te sera pas utile pour un usage même très approfondi de VBA>Excel.
Mais je te rassure tu as bien compris le principe : On peux supposer que tout objet est un élément d'une classe.
Je ne sais pas si au niveau sémantique on peut dire que l'objet est créé par la classe.
Toujours à mon avis, au niveau de la programmation usuelle... on s'en fout complètement. Il n'y à guère que les programmeurs de Microsoft qui conceptualisent ça de cette manière !
A+
- Messages
- 4'199
- Excel
- 2021 FR 64 bits
- Inscrit
- 13/06/2016
- Emploi
- bénévole associations Goutte d'Or
Bonsoir,
Une classe est par définition un ensemble d'éléments possédant les mêmes propriétés, événements et méthodes (actions).
Toute classe Microsoft possède une structure définissant ces propriétés, événements et méthodes, cette structure étant stockée dans une bibliothèque.
L' instance d'une classe est la personnalisation de cette structure pour un élément de cette classe, personnalisation permettant à l'exécution, de stocker en mémoire les propriétés, événements et méthodes spécifiques à cet élément.
Exemple de code :
Dim F1 as Worksheet, F2 as WorkSheet
set F1 = Sheets(1) 'assignation variable objet F1 à la première feuille du classeur
set F2 = Sheets(2) 'assignation variable objet F2 à la deuxième feuille du classeurAvec ce code, 2 instances de la classe WorkSheet ont été créées, ces instances étant respectivement associées aux 2 premières feuilles du classeur.
En fait, les objets qu'on manipule en VBA, ce sont bien les instances de classe.
Si maintenant, je reprends ton propos via cet élément dans une instruction :
Range("A:A").CellsL'élément est la colonne A et une instance de classe Range a été créée pour cet objet, instance qui stocke en particulier la propriété "Cells" associée à cet élément. L'instance contient donc toutes les cellules de la colonne A.
L'objet VBA est Range("A:A"), instance de la classe Range pour l'élément : colonne A.
Range.Cells ne représente aucun objet VBA mais uniquement la propriété "Cells" de la classe Range.
Mais Galopin a raison, pour la programmation usuelle, ce concept ne te servira pas vraiment. Il sera un peu plus utile si un jour tu manipule des modules de classe.
Bonjour,
est-ce que cela veut dire que lorsque j'écris "Range.cells" dans mon code, je crée un objet cellule (alors que dans la documentation c'est annoncé comme une propriété...)?
En fait il n'y a pas d'objet cellule, vba ne connait que le Range.
Un range est un objet d'une ou plusieurs cellules. Que ce soit une cellule, une plage quelconque, une colonne, une sélection 3D, c'est un objet Range.
Cells n'est pas un événement, ça ne peut pas être une méthode puisqu'il n'y a pas d'action. C'est donc une propriété, qui te retourne un objet Range. Comme les poupées russes.
Comme dit précédemment, ne prend pas trop la tête avec ça, tu apprendras vite à voir que tu as affaire à un objet.
Ne serait-ce qu'en travaillant proprement et en déclarant et typant tes variables.
Pour initialiser un objet tu es obligée d'utiliser Set (comme l'a fait Thev au-dessus)
Si tu écris :
c= range("A1")Tu crois avoir un range mais tu as un Variant qui contient la valeur.
avec :
Set c= range("A1")Là tu as un Variant/Object/Range
Maintenant si tu as coché dans les options de VBE 'Déclaration obligatoire des variables' (ce qui est fortement conseillé), tu es obligée de le faire, et tant qu'à faire tu la types correctement.
Dim c As Range
' avec c= range("A1") maintenant tu te fais jeter, alors qu'au-dessus c'est passé et tu aurais pu passer du temps à trouver ton bug
Set c = range("A1") ' c'est bonEt si tu écris :
Dim c As Variant 'ou As Double si tu attends un nombre exclusivement, ou ...
' avec Set c= range("A1") tu te fais jeter
c = range("A1"). Value ' c'est bonIndiquer la propriété .Value n'est pas obligatoire (propriété par défaut) mais c'est une bonne habitude à prendre.
Déjà en lisant on sait sans ambiguïté ce que tu veux. Si tu ne le fais pas tu laisses excel choisir. Le plus souvent ça sera bon, mais parfois ça ne sera pas la propriété que tu penses qu'il aura choisi. Et là encore tu peux y passer du temps à trouver...
J'espère que je ne t'ai pas trop embrouillée.
En résumé : déclare et type tes variables (pas As Variant sauf si volontairement, mais au plus près du besoin), et tu y verras clair au fil de tes saisies.
Pour assurer le coup (t'embrouiller), un petit exercice
Dim pl As Range
Set pl = Range("C2:F5").Range("B2:C3").Cells(2, 1)Quelle est l'adresse du range pl ?
(pense aux poupées russes)
eric
Bonjour Eric,
Euh... Chui pas sur que ton dernier exemple va l'aider beaucoup dans sa compréhension de VBA !
A+
Bonjour à tous,
Rhooo, tu crois ?
eric
Merci à tous pour vos retours
Je vais étudier tout ça et je reviens vers vous...
Merci de ne pas répondre à la question d'Eriiic...
Me revoilà...
Réponse à Eriiic, je dirais (en marchant sur des oeufs..) que c'est Cells(2,1)???
Ne rigolez pas je suis archi débutante...
L'idée pour moi c'est de pouvoir programmer en donnant du sens, du coup, je me dis que rien de tel que la doc mise à disposition pour se repérer....
Donc j'ai essayé ça:
Sub essai()
'erreur 438:
Dim F1 As Worksheet, F2 As Worksheet
Set F1 = Sheets(1) 'assignation variable objet F1 à la première feuille du classeur
Set F2 = Sheets(2) 'assignation variable objet F2 à la deuxième feuille du classeur
F1.Cells(1, 1).Copy 'ok, sélectionne la cellule
F2.Cells(1, 1).Paste 'méthode non gérée par cet objet...alors que .Paste est annoncé dans la doc comme étant une méthode de Worksheet...why?
End SubPourquoi .paste ne fonctionne pas alors que cette méthode est annoncée dans la doc comme appartenant à WorkSheet?
Même problème ici:
Sub essai()
Range("A:A").Cells (1,1) 'erreur de compilation...pourquoi, alors que cells est annoncé comme une propriété de Range?
'L'objet VBA est Range("A:A"), instance de la classe Range pour l'élément : colonne A.
'Range.Cells ne représente aucun objet VBA mais uniquement la propriété "Cells" de la classe Range.
Range.Copy
End Sub
-----------------------------------------------------------------------------------------------
Sub essai()
Range(Cells(1, 1)).Copy
'méthode qui a échoué
Range(Cells(2, 1)).PasteAlors que dans ce cas ça fonctionne:
Sub essai()
Dim c As Range
'cette fois-ci les méthodes annoncées par la doc fonctionne
Set c = Range("A1")
Set d = Range("A2")
c.Clear
d.Clear
End SubMerci, merci
Au moins tu es méthodiques et appliquée, c'est bien
Réponse à Eriiic, je dirais (en marchant sur des oeufs..) que c'est Cells(2,1)???
Perdu. Et par adresse j'entend la référence de la cellule ou plage résultante. Comme A1
F2.Cells(1, 1).Paste 'méthode non gérée par cet objet...alors que .Paste est annoncé dans la doc comme étant une méthode de Worksheet...why?
dommage, tu l'avais dans l'aide. "méthode de Worksheet" et tu l'appliques à un Range, autre type d'objet.
F2.Paste passera, seulement le collé se fera dans la cellule active. Que tu ne peux choisir que si F2 est la feuille active...
Si c'est uniquement la valeur qui t'intéresse (sans les formats) tu as :
F2.Cells(1, 1).value = F1.Cells(1, 1).value
Range("A:A").Cells (1,1) 'erreur de compilation...pourquoi, alors que cells est annoncé comme une propriété de Range?
Propriété oui, mais qui te retourne un Range.
Mis tout seul ça ne veux rien dire.
C'est comme si tu écrivais 3 tout seul, ça ne veut rien dire. a = 3, là ça prend sens.
Soit tu utilises ce range (comme l'affecter à une variable), soit tu lui appliques une méthode (.Copy), soit tu lui changes une propriété (.Font.Color = vbRed), etc
eric
Bonsoir,
Il ne faut pas être trop dur avec les novices de bonne volonté. On risque de les décourager. On sait bien que la réponse à la question d'Eriiic se simplifie après commutativité, associativité et toutes les commodités en Cells(2, 3)(2, 2)(2).
Bon courage AxelleGreen. Bravo à ta persévérance et à tes efforts pour assimiler le VBA.
C'est à prendre comme un jeu MaPomme, je sais que tu l'as pris comme tel
- Messages
- 4'199
- Excel
- 2021 FR 64 bits
- Inscrit
- 13/06/2016
- Emploi
- bénévole associations Goutte d'Or
Bonsoir,
Sub essai() Dim F1 As Worksheet, F2 As Worksheet Set F1 = Sheets(1) 'assignation variable objet F1 à la première feuille du classeur Set F2 = Sheets(2) 'assignation variable objet F2 à la deuxième feuille du classeur F1.Cells(1, 1).Copy 'ok, copie la cellule A1 de la feuille F1 F2.Cells(1, 1).Paste End SubPourquoi .paste ne fonctionne pas alors que cette méthode est annoncée dans la doc comme appartenant à WorkSheet?
Tout simplement parce que l'objet F2 muni de la propriété Cells(1,1) représente la cellule A1 de la deuxième feuille du classeur, soit une plage (Range) d'une cellule.
F2.Cells(1, 1) appartient donc à la classe Range et non à la classe WorkSheet. La méthode de collage pour la classe Range est "PasteSpecial".
Ceci sera mieux et plus clair au niveau du code
F2.Cells(1, "A").PasteSpecial (xlPasteAll)Essai2
Set c = Range("A1")
Set d = Range("A2")Par ailleurs, pour la clarté du code, éviter d'utiliser une seule lettre pour une variable objet. Une variable d'une lettre est en principe réservé aux indices.
Puisqu'il s'agit de cellules, les variables c1 et c2 sont meilleures ou encore plus explicite, cel1 et cel2.
@ Eriiic, 2 ème essai, en tapant ce code:
Sub essai()
Dim pl1 As Range, pl2 As Range, pl3 As Range
Set pl1 = Range("C2:F5")
pl1.Interior.Color = vbRed
Set pl2 = Range("C2:F5").Range("B2:C3")
pl2.Interior.Color = vbGreen
Set pl3 = Range("C2:F5").Range("B2:C3").Cells(2, 1)
pl3.Interior.Color = vbBlue
End SubJe trouve D4?
Maintenant, en tapant ce code:
Sub essai()
'fonctionne:
Dim F1 As Worksheet, F2 As Worksheet
Set F1 = Sheets(1) 'assignation variable objet F1 à la première feuille du classeur
Set F2 = Sheets(2) 'assignation variable objet F2 à la deuxième feuille du classeur
F1.Cells(1, 1).Copy 'ok, sélectionne la cellule
F2.Select
Dim F3 As Range
Set F3 = Cells(1, 1)
F3.PasteSpecial
End SubVoici ma petite synthèse:
Les modèles d'objets sont des classes avec des propriétés, des méthodes, des évènements.
Worksheet est par exemple l'un de ces modèles...
Lorsqu'on crée une instance de cette classe, avec des propriétés, ici "Cells", dès lors, ces propriétés peuvent ( c'est le cas pour Cells) renvoyer un objet (dans notre cas "Range") qui va fonctionner différemment de nos objets de départ (F1 et F2)... alors qu'il est inclus dedans...F3 est dans F2,mais il n'a pas les mêmes propriétés, méthodes etc. car on bascule dans une autre poupée russe (ici Range), avec des fonctionnalités différentes...
Bilan, dans la doc, regarder ce que la méthode, propriété etc retourne, car le résultat nous fait basculer dans une autre poupée russe qui fonctionne différemment...?
- Messages
- 4'199
- Excel
- 2021 FR 64 bits
- Inscrit
- 13/06/2016
- Emploi
- bénévole associations Goutte d'Or
Worksheet est par exemple l'un de ces modèles...
Lorsqu'on crée une instance de cette classe, avec des propriétés, ici "Cells", dès lors, ces propriétés peuvent ( c'est le cas pour Cells) renvoyer un objet
Bravo pour la synthèse.
Set F1 = WorkSheets(1) renvoie un objet VBA : F1, instance de la classe WorkSheet pour la 1ère feuille du classeur
Set C1 = WorkSheets(1).Cells(1,"A")renvoie un objet VBA : C1, instance de la classe Range pour la cellule A1 de la1ère feuille du classeur
Bravo
En plus, tu l'as imaginée en récoltant d'autres outils dispersés ailleurs, re bravo
Ce que je voulais te faire sentir à travers ce jeu (facultatif), c'est que Range s'applique à l'expression dont il est issu.
Range("C2:F5") fait référence à Worksheets("Feuil1").Cells, qu'on écrit pas le plus souvent.
Dans Range("C2:F5").Range("B2:C3"), B2:C3 est calculé depuis C2:F5.
Range("C2:F5").Range("B2:C3") est équivalent à Range("D3:E4"). Ce que tes couleurs doivent très bien montrer.
Une parenthèse, ne te met pas des pièges toi-même en nommant tes variables.
Dim F1 As Worksheet, F2 As Worksheetok, on comprend que Fx est une feuille. Mais plus bas :
Dim F3 As RangeN'oublie pas que tes noms sont sensés t'aider (et tes lecteurs), et éventuellement auto-documenter le code. Dans 3 mois, si tu dois revenir dessus ça t'obligera à une réflexion quand tu verras un Fx. Range ? Worksheet ?
Et ta langue à fourché dans ta synthèse :
F3 est dans F2
eric
Merci pour tous ces messages, c'est très encourageant...
Mais pourquoi ma langue a t-elle fourché: F3 ne devient-il pas un élément dans F2? Une petite poupée russe dans une plus grande?
( bon je sais, c'est pas très clair car effectivement mes variables ne sont pas du tout explicites...)
De la même façon que (dans le code d'Eric) Range("C2:F5").Range("B2:C3") , appartient à Range("C2:F5")?
- Messages
- 4'199
- Excel
- 2021 FR 64 bits
- Inscrit
- 13/06/2016
- Emploi
- bénévole associations Goutte d'Or
Mais pourquoi ma langue a t-elle fourché: F3 ne devient-il pas un élément dans F2?
F3 est certes un élément de F2, mais il n'appartient pas à la même classe. F2 appartient à la classe des feuilles (WorkSheet), tandis que F3 appartient à la classe des plages (Range). Le nom de variable F3 est illogique et ne concourt donc pas à la clarté du code.
Une variable plus logique serait par exemple C1 ou Cell1 puisqu'il s'agit d'une seule cellule :
set C1 = Cells(1,"A") ou plus explicite
set Cell1 = Cells(1,"A")S'il s'agit d'une plage de plusieurs cellules :
Set pl1 = Range("C2:F5")ou plus explicite
Set plage1 = Range("C2:F5")Ne jamais oublier que dans un code, le choix du nom des variables est primordial pour en faciliter la composition et la lecture. Des noms de variable peu explicites ou sans rapport avec leur contenu rendent vite un code incompréhensible.
Mais pourquoi ma langue a t-elle fourché: F3 ne devient-il pas un élément dans F2?
Ah ben voilà, je me suis fait avoir. Quand je te disais que c'était piégeux ton système de noms
En lecture rapide, pour moi c'était 2 feuilles...
eric
Un grand Merci à vous tous pour votre aide!!
Me voilà bien éclairée sur ce sujet!!
Maintenant il n'y a plus qu'à mettre la main à la pâte!!
A bientôt pour d'autres aventures VBA!
Bonjour,
Qu'elle peut d'ailleurs comparer avec :
Sub Test()
Dim pl As Range
Set pl = Range("C2:F5").Range("B2:C3").Cells(2, 1)
MsgBox pl.Address(0, 0) & vbCrLf & Cells(2, 3)(2, 2)(2).Address(0, 0) & vbCrLf & Cells(4, 4).Address(0, 0)
End Sub