VBA Module de classe

avaya

XLDnaute Nouveau
Bonjour,

J'ai réalisé des procédures/fonctions imbriquées les unes dans les autres, assez longues comportant beaucoup de tableaux à plusieurs dimensions.

La macro risque d'être modifiée à l'avenir par d'autres utilisateurs et de générer des erreurs.
Pour cela, j'aimerais faciliter sa compréhension en créant un/des module(s) de classe.

Seulement voilà: les classes, c'est nouveau pour moi et j'ai beau chercher des exemples sur le net, je n'arrive pas à les transposer sur mon cas.
J'aimerais savoir si quelqu'un voudrait bien m'aider...

En fichier joint, je vous ai mis une simplification de ce que j'ai fait.
Je souhaiterais simplement la même chose mais avec un module de classe, enfin si c'est faisable.

Merci d'avance,

avaya
 

Pièces jointes

  • Légumes.xlsm
    16.2 KB · Affichages: 36
  • Légumes.xlsm
    16.2 KB · Affichages: 35
  • Légumes.xlsm
    16.2 KB · Affichages: 40

Dranreb

XLDnaute Barbatruc
Re : VBA Module de classe

Bonjour.

Un module de classe est à la fois un modèle d'objet, son plan de construction et la programmation destinée à fonctionner sur les exemplaires qui en seront créés. Dans le jargon on appelle ces exemplaires des "instances" pour bien les distinguer de leur type, qui n'est autre que le nom du module de classe. Celui ci devient en effet d'office un type de donnée, de sorte qu'on peut le préciser derrière As dans une déclaration Dim ou Private.
Dans la programmation extérieure au module de classe on ne voit de celui ci que les élément précisés avec le mot clé Public, mais, à la différence d'un module ordinaire, on ne peut y accéder qu'à condition de le faire précéder d'un point, puis encore devant, à moins d'une instruction With préalable le disant déjà, d'une expression représentant une instance de cet objet (sinon: erreur de compilation). S'il s'agit d'une variable de votre crû, il faut en outre qu'une expression de ce type ait été affectée par un Set à cette variable d'instance (sinon: erreur d'exécution, cette fois). Fort heureusement, l'expression formée du mot clé New suivi du type d'objet (qui est en même temps le nom de son module de classe) représente une instance tout juste créée de ce type d'objet.
Propriétés et méthodes sont les appellations conventionnelles de ces élements visibles de l'extérieur du module de classe, déjà vues dans l'aide de VBA à propos des objets de bibliothèques fournies. Une chose déclarée Public dans un module de classe a un statut de propriété quand il s'agit d'une simple variable, d'une Function ou d'une Property Get dépourvues de paramètre, ou d'une Property Let ou Set munie d'un seul paramètre. Dans tous les autre cas il s'agit d'une méthode, en particulier quand c'est une Sub avec ou sans paramètre.
Enfin, un objet peut aussi décréter des évènements dans un autre module objet. Pour cela, il doit y être déclaré en tête avec le mot clé WithEvents. Cela a pour conséquence d'installer son nom dans la liste de gauche (Objet) qui surmonte la fenêtre de code. S'il y est sélectionné, celle de droite (Procédure) propose les différents modèles de procédures pouvant être installés automatiquement pour gérer ces évènements. Dans le module de classe, ces évènements sont déclarés au moyen d'instructions Event, et, dans les exécutions, décrétés par des RaiseEvent.

C'est en considérant cela que vous pouvez décider si un module de classe pourrait simplifier l'écriture des fonctionnalités dont vous aurez besoin. À première vue il ne me semble pas. En revanche des Dictionary pourraient être fort utiles à la place de tableaux, et en particulier des dictionnaires arborescents, c'est à dire dont les items sont soit des listes de numéros de lignes dans la plage source qui a servi à le constituer, soit eux mêmes des dictionnaires arborescents pour les colonnes restantes, ce qui permet de retrouver instantanément une information à partir de plusieurs clés hiérarchiques.

Si le choix du légume et d'une couleur ou d'une saison est effectué dans des ComboBox d'un Userform, là oui, j'ai défini, si ça vous intéresse un objet de type ComboBoxLiés qui se comporte un peut comme un super-ComboBox. Il suffit pratiquement de lui annoncer au début chacun des ComboBox à gérer accompagné de la colonne d’où tirer sa List et ensuite il décrète des évènements pour récupérer les choix effectués.
 
Dernière édition:

Iznogood1

XLDnaute Impliqué
Re : VBA Module de classe

Ton exemple avec 2 modules de classe :
  • 1 permettant de créer un objet légume
  • 1 permettant de créer un objet panier

Le panier contient des légumes.
Il possède 2 propriétés : MontantLegumeCouleur et MontantLegumeCouleur

Et un module standard pour lancer une démo.

Tu devrais vite capter la logique des classes.
 

Pièces jointes

  • Légumes.xlsm
    26.2 KB · Affichages: 53
  • Légumes.xlsm
    26.2 KB · Affichages: 44
  • Légumes.xlsm
    26.2 KB · Affichages: 44

avaya

XLDnaute Nouveau
Re : VBA Module de classe

Dranreb, Iznogood1,

Je vous remercie pour vos réponses.
Je n'ai pas pu regarder vos messages la semaine dernière, voilà pourquoi je tarde à vous répondre.

A Iznogood1:
Je vais regarder attentivement ta macro pour comprendre comment ça fonctionne.
Merci beaucoup!

A Dranreb:
Je ne connaissais pas le Dictionary avant. Cet outil semble effectivement très intéressant! Je vais de ce pas faire des recherches pour voir si cela peut mieux répondre à mes besoins. En revanche, je n'ai pas besoin d'une combobox. Merci quand même pour la proposition.

Je reviendrai vers vous si j'ai d'autres questions mais à priori ça devrait le faire!

Merci encore,

avaya
 

avaya

XLDnaute Nouveau
Re : VBA Module de classe

Iznogood1,

Petite question, si toutefois tu vois mon post...
Dans le module standard, est-ce qu'il est possible de faire varier l'une des trois composantes (nom, couleur, saison) pour arriver à un résultat qui ressemblerait à ça:

For each nom in (?)
MsgBox .MontantLegumeCouleur(nom, "Rouge")
Next nom

ou

For Each couleur in (?)
MsgBox .MontantLegumeCouleur("Tomate", couleur)
Next couleur

Je peux contourner le problème avec ce que je sais faire (mes array dans des fonctions: ce que j'ai fait en fichier joint ci-dessous) mais ça serait mieux avec les classes.

Merci d'avance,

avaya
 

Pièces jointes

  • Classes - Exemple Légumes1.xlsm
    28.2 KB · Affichages: 27

Dranreb

XLDnaute Barbatruc
Re : VBA Module de classe

Si ça vous intéresse, et si en particulier l'algorithme doit se baser sur les données de la feuill1, j'ai une fonction GroupOrg capable d'organiser vos données en collections imbriquées pouvant s'explorer par des For Each…In XX.Contenu.
Les éléments de la collection sont des SsGroup, un type d'objet (et donc un module de classe) extrêmement simple muni d'une propriété Id As Variant et d'une autre Contenu As Collection.
 

avaya

XLDnaute Nouveau
Re : VBA Module de classe

Bonjour à tous,

Dranreb: J'ai regardé vos macros mais ce que j'aimerais faire c'est faire un module de collection, pas une fonction, donc finalement ça ne m'intéresse pas dans ce cas là. J'ai trouvé un site qui semble expliquer comment faire:
Productive Bytes: VBA Strongly typed collections
Je n'ai pas ecore vérifié si ça fonctionne vraiment.

J'ai une question, certainement très stupide (concepts de base en VBA?) concernant l'appel à une procédure. Le détail de ma question se trouve dans le module 2 du fichier joint.

Merci encore

avaya
 

Pièces jointes

  • Classes - Exemple Légumes2.xlsm
    30.6 KB · Affichages: 19
  • Classes - Exemple Légumes2.xlsm
    30.6 KB · Affichages: 29
  • Classes - Exemple Légumes2.xlsm
    30.6 KB · Affichages: 24

Dranreb

XLDnaute Barbatruc
Re : VBA Module de classe

Bonjour.
'Mais la ligne juste en dessous ne fonctionne pas quand on exécute la procédure! Pourquoi?
MsgBox caddie1.NomPanier(panier1).MontantLegumeCouleur("Tomate", "Rouge")
Parce que NomPanier est une propriété de l'objet objCaddie, non une méthode admettant un paramètre.
Le paramètre d'une Property Let n'en est pas vraiment un. C'est ce qu'on veut lui affecter, et qui se met derrière le signe égal de l'affectation.

À mon avis les modules de classe c'est surtout très utile pour définir des objets très techniques d'aide au traitement.
Je suis très sceptique quant à l’intérêt de représenter par des objets, au sens VBA, les entités de la réalité gérée.
Ne serait-ce que parce qu'une programmation ne peut pas manipuler la réalité, tandis qu'un objet au sens VBA est en réalité un dispositif destiné à représenter et manipuler une entité. Un objet de type Worksheet n'est pas une feuille de calcul Excel, mais un truc qui en représente une et permet de la manipuler.
 
Dernière édition:

avaya

XLDnaute Nouveau
Re : VBA Module de classe

Bonjour,

Pour info, j'ai réussi à faire marcher ce qui est expliqué dans le lien que j'ai posté dans mon message précédent en utilisant VB6.
Des explications plus claires sur comment mettre les Attributes dans VB6 se trouvent dans le lien ci-dessous:
VB Helper: HowTo: Create a custom collection that supports For Each
Je mets mon fichier en pièce jointe au cas où quelqu'un serait intéressé.
Dranreb, je vous remercie encore pour votre aide.

avaya
 

Pièces jointes

  • Classes - Exemple Légumes2.xlsm
    39.3 KB · Affichages: 28
  • Classes - Exemple Légumes2.xlsm
    39.3 KB · Affichages: 36
  • Classes - Exemple Légumes2.xlsm
    39.3 KB · Affichages: 39

Dranreb

XLDnaute Barbatruc
Re : VBA Module de classe

Bonjour.

À mon avis vous devriez séparer les classes éléments des classes Collection. De plus ces dernières n'apportent rien si c'est pour faire exactement la même chose qu'avec une Collection ordinaire. Si encore vous vous y chargiez automatiquement de la clé, mise en conformité avec une propriété Name de l'élément…
Ça n'interdirait pas de déclarer une variable Parent As Collection pour la classe élément, mais il ne faut pas y faire un Set = New Collection dans la Sub Class_Initialize mais prévoir une méthode pour l'initialiser à la collection dont cet élément fait partie.
 

avaya

XLDnaute Nouveau
Re : VBA Module de classe

Bonjour à tous,


Toujours dans le même projet, je fais face à un nouveau problème que j'essaie de résoudre depuis quelques jours mais je vois pas de réponse par moi-même.


Ce que je souhaite:
Lorsque j'attribue un nouveau légume dans un panier (qui est lui-même dans un caddie), au moment où je définis sa couleur, je voudrais que la couleur soit également stockée dans une liste (collection) indépendament du légume/panier/caddie.

Ce que j'ai fait (et qui ne fonctionne pas):
J'ai donc créé un module de classe ObjCouleur avec une collection à l'intérieur.
Mon souci se trouve dans le module ObjLegume dont voici un extrait:

Private l_couleur As String
Private col As New ObjCouleur

Public Property Let couleur(v As String)
l_couleur = v
Call col.test(l_couleur)
End Property

A chaque fois qu'un nouveau légume est créé, un nouveau col dans ObjCouleur est lui aussi créé.
Alors que je voudrais qu'à chaque fois qu'un nouveau légume est créé, le même col lui soit affecté.
Dans le test que j'ai mis en place, on voit bien que la liste de couleurs reste à 2 alors qu'elle devrait être à 8 à la fin de la macro (module2).


Même si je pense avoir cerné le problème, je n'arrive pas à le résoudre... aidez-moi s'il vous plaît!


Dranreb: Je m'excuse de continuer dans cette voie là mais j'aimerais vraiment comprendre comment ça fonctionne.


avaya
 

Pièces jointes

  • Classes - Exemple Légumes2.xlsm
    45.7 KB · Affichages: 31
  • Classes - Exemple Légumes2.xlsm
    45.7 KB · Affichages: 35
  • Classes - Exemple Légumes2.xlsm
    45.7 KB · Affichages: 23

avaya

XLDnaute Nouveau
Re : VBA Module de classe

Bonjour tout le monde,

J'ai finalement réussi à faire ce que je voulais.
Effectivement, mon problème venait bien du fait que je créais un nouveau col dans objCouleur à chaque légume ajouté.
Il fallait déclarer col en public dans le module standard.

Je mets la nouvelle version de mon fichier en pièce jointe.
Ca pourra peut-etre intéresser quelqu'un un jour.

avaya
 

Pièces jointes

  • Classes - Exemple Légumes2.xlsm
    50.8 KB · Affichages: 46
  • Classes - Exemple Légumes2.xlsm
    50.8 KB · Affichages: 50
  • Classes - Exemple Légumes2.xlsm
    50.8 KB · Affichages: 59

Discussions similaires

Membres actuellement en ligne

Statistiques des forums

Discussions
312 508
Messages
2 089 143
Membres
104 049
dernier inscrit
Xavier.L