Structure en Arbre n-aire en VBA

tototiti2008

XLDnaute Barbatruc
Bonjour à toutes et tous,

J'ai pensé à essayer de reproduire certaines structures classiques de programmation en VBA, et je me suis intéressé aux arbres (n-aires), c'est à dire simplement la représentation d'une hiérarchie parent-enfants, quel que soit le nombre d'enfants et quel que soit le nombre de niveaux (petits-enfants, etc...)
Je voulais savoir si vous aviez connaissance de quelque chose d'existant sur le sujet (éviter de réinventer la roue ;)) ou une piste de structuration de ce type de hiérarchie

Le but sera ensuite de rendre cette structure assez souple (possibilité d'ajouter/supprimer des branches de la hiérarchie, facilités de parcours des branches, recherche...etc)

Merci
 
Dernière édition:

BOISGONTIER

XLDnaute Barbatruc
Repose en paix
Re : Structure en Arbre n-aire en VBA

@ Efgé
Ton exemple n'est pas une véritable arborescence

Sur la version en PJ(ArbreBis), j'ai contourné le problème.

J'ai ajouté le code en programmation classique

Code:
Dim mondico
Sub essai()
  Set mondico = CreateObject("scripting.dictionary")
  ajout "bb,aa"
  ajout "cc,aa"
  ajout "dd,aa"
  ajout "ee,bb"
  ajout "ff,bb"
  ajout "gg,dd"
  ajout "hh,ee"
  ajout "ii,ee"
  ajout "jj,hh"
  ajout "kk,hh"
  MsgBox affiche()
  SupPère "bb"
  MsgBox affiche()
End Sub

Sub SupPère(père)
   vpersonnes père, 1
End Sub

Sub ajout(FilsPère)
  a = Split(FilsPère, ",")
  clé = a(0): élem = a(1)
  mondico(clé) = élem
End Sub

Function affiche()
  tmp = ""
  For Each c In mondico.keys
   If mondico(c) <> "" Then tmp = tmp & "Fils:" & c & " - père:" & mondico.Item(c) & vbLf
  Next c
  affiche = tmp
End Function

Sub vpersonnes(parent, niv)       ' procédure récursive
  For Each c In mondico.keys
    If mondico.Item(c) = parent Then vpersonnes c, niv + 1
  Next c
  mondico.Remove parent
End Sub

Module de classe avec un tableau

Code:
Private Tbl(1 To 100, 1 To 3)
Private n, branche
Public Property Let ajout(FilsPère)
  a = Split(FilsPère, ",")
  clé = a(0): élem = a(1)
  n = n + 1
  Tbl(n, 1) = clé: Tbl(n, 2) = élem
End Property

Public Property Let SupBranche(père)
   SupItem père, 1
    For i = n To 1 Step -1
     If Tbl(i, 3) = "sup" Then
        For k = i To n
           Tbl(k, 1) = Tbl(k + 1, 1)
           Tbl(k, 2) = Tbl(k + 1, 2)
           Tbl(k, 3) = Tbl(k + 1, 3)
        Next k
        n = n - 1
     End If
   Next i
End Property

Public Property Get VisuBranche(père)
   visu père, 1
   VisuBranche = branche
End Property

Public Property Get affiche()
  tmp = ""
  For p = 1 To n
   If Tbl(p, 1) <> "" Then tmp = tmp & "Fils:" & Tbl(p, 1) & " - père:" & Tbl(p, 2) & vbLf
  Next p
  affiche = tmp
End Property

Public Property Get père(fils)
   For i = 1 To n
     If Tbl(i, 1) = fils Then père = Tbl(i, 2)
   Next i
End Property

Public Property Get taille()
  taille = n
End Property

Sub SupItem(parent, niv)       ' procédure récursive
  For i = 1 To n
    If Tbl(i, 2) = parent Then SupItem Tbl(i, 1), niv + 1
  Next i
  For k = 1 To n
   If Tbl(k, 1) = parent Then Tbl(k, 3) = "sup"
  Next k
End Sub

Sub visu(parent, niv) ' procédure récursive
  branche = branche & parent & vbLf
  For i = 1 To n
    If Tbl(i, 2) = parent Then visu Tbl(i, 1), niv + 1
  Next i
End Sub

Ajout d'un arbre à un autre

http://boisgontierjacques.free.fr/fichiers/Cellules/ClasseArbreTableau.xls

Code:
Sub AjoutArbreAunAutre()
   Set a = New Arbre
   Set b = New Arbre
   '--- arbre a
   Set f = Sheets("bd")
   For i = 2 To f.[A65000].End(xlUp).Row
     a.ajout = f.Cells(i, 1) & "," & f.Cells(i, 2)
   Next i
   '--- arbre b
   b.ajout = "nn,mm"
   b.ajout = "oo,mm"
   b.ajout = "pp,nn"
   b.ajout = "qq,pp"
   '--- on ajoute arbre b à la branche ee de l'arbre a
   aa = Split(b.liste(), ":")
   bb = Split(aa(0), ",")
   a.ajout = bb(1) & ",ee"    ' on raccroche la branche mm  de b à ee de a
   For i = LBound(aa) To UBound(aa)
     a.ajout = aa(i)
   Next i
   a.DessineBrancheShapes = "aa,feuil3"
   Sheets("feuil3").Select
End Sub


JB
 

Pièces jointes

  • ClasseArbreBis.xls
    71 KB · Affichages: 130
  • ClasseArbreTableau.xls
    105.5 KB · Affichages: 126
  • ClasseArbreTableau.xls
    105.5 KB · Affichages: 110
  • ClasseArbreTableau.xls
    105.5 KB · Affichages: 113
Dernière édition:

tototiti2008

XLDnaute Barbatruc
Re : Structure en Arbre n-aire en VBA

Bonjour Boisgontier, Bonjour Efgé, :)

Impressionnant, merci
Comme j'ai commencé, je continuerais surement à la faire sur base de mon départ, ne serait-ce que pour m'habituer à la construction d'une classe, tout sauf naturel pour moi pour l'instant...
 

tototiti2008

XLDnaute Barbatruc
Re : Structure en Arbre n-aire en VBA

Bonjour à tous,

Je reviens sur ce fil pour vous dire que ça avance, mais doucement, pour ceux qui voudraient voir le résultat (bien que la classe de Boisgontier fasse déjà le plus gros du travail ;))
J'en profite pour essayer de bien comprendre les concepts de base d'un classe, Objet collection avec sous-objet, comment définir la propriété Parent du sous-objet, comment générer les évènements... sont autant de points sur lesquels je passe pas mal de temps, voire rame pas mal
C'est vraiment une autre façon d'appréhender la programmation, d'où mon envie d'en faire un exemple assez complet
Pour l'instant, j'ai toujours fini par trouver une solution à mes blocages, parfois en prenant pas mal de temps, ceci dit je ne manquerais pas de poster le résultat une fois terminé :)
Le blocage du moment : comment générer un évènement dans l'Objet Parent si un évènement s'est déclenché dans le sous-objet... finirais par trouver :D
 

Orodreth

XLDnaute Impliqué
Re : Structure en Arbre n-aire en VBA

Re,

A ma connaissance, 2 méthodes pour gérer les évènements:
Un objet A se retrouve dans un certain état et doit déclencher un évènement chez l'objet B et l'objet C
==> 1 ere méthode) B et C écoutent l'état de A, et sont en attente. L'évènement se déclenche au changement d'état de A
==> 2eme méthode) B et C font leurs vies, A change d'état et signale à B et C qu'il a changé. De fait, B et C agissent en conséquence et déclenchent leur évènement en réponse à A.

Personnellement, je n'aime pas la 1ere méthode qui freeze certains éléments de l'application, donc j'ai tendance à gérer la seconde.

Et comme je n'y entends généralement rien avec la notion d'Event et de RaiseEvent, j'ai monté mon propre moteur.

Ca donne un truc comme ça:

Code:
Class A
      private maString1 as String
      private mesAbonnes as collection

      public Sub AjouterAbonne(unObjet as Object)
              mesAbonnes.add unObjet
      end sub

      public property LET String1 (s as string)
               maString1 = s
               Dim o as object
               for each o in mesAbonnes
                    o.[B][I]traitementAFaire[/I][/B] 'traitementAFaire DOIT ETRE une méthode commune à tous les objets de la collection, même s'ils ne sont pas du même type
               next o
      end property
end class

Class B
       public sub Init (unA as A)
             ...traitements divers
             ...traitements divers
             unA.AjouterAbonne B
       end sub

       public sub traitementAFaire()
             ...
             ...
      end sub
end class

Class C
       public sub Init (unA as A)
             ...traitements divers
             ...traitements divers
             unA.AjouterAbonne C
       end sub

       public sub traitementAFaire()
             ...
             ...
      end sub
end class
C'est un peu barbare, et certainement brut de décoffrage, mais ça marche bien quand on est rigoureux sur le modèle qui va avec.

Cordialement,
Oro
 
Dernière édition:

tototiti2008

XLDnaute Barbatruc
Re : Structure en Arbre n-aire en VBA

Re,

Merci
Cependant la méthode "traitementAFaire" est publique pour tous les objets, donc sera susceptible d'être lancée dans le code utilisant un objet de la classe (ce qui me gêne un peu), pas possible de la mettre en private je suppose sinon elle ne sera pas appelable depuis une autre classe...
C'est là qu'il faut commencer à jouer avec des héritages ? je sens le mal de tête arriver ;)

Edit : ou alors il faut appeler un ami (Friend)... mais je crois que Friend permet d'appeler la méthode de tout le projet, même d'un module classique, et je doute que Rachel, Joe, Monica, Ross, Phoebe et Chandler m'aident beaucoup sur le coup là :D
 
Dernière édition:

Orodreth

XLDnaute Impliqué
Re : Structure en Arbre n-aire en VBA

Dans l'absolu, je te dirais oui.

En programmation objet, il est effectivement possible de gérer différents niveaux de visibilité, de sortes de gérer la portée de tes attributs et de tes méthodes finement.
Et effectivement, l'héritage entre en ligne de compte.

Malheureusement, ce n'est que de la théorie. En DotNet avec Visual Studio, en Java, en Delphi, oui, c'est possible, et oui, ça marche.

En excel ... J'ai bien peur de n'avoir vu que 2 niveaux de visibilité: private et public.
Ce qui n'est pas évident pour ce que tu décris.

Maintenant, bon, c'est aussi le but que la méthode en question puisse être atteinte de l'extérieur, le principe même des abonnés.

Globalement, la méthode avec Event et RaiseEvent revient à peu près au même.
Quoi que à voir, il est peut-être possible (voire probable) d'avoir un private Event dans la classe qui reçoit l'alerte.
le RaiseEvent, lui, par contre, est obligatoirement public.

Si quelqu'un est plus calé que moi sur la notion d'Event et de RaiseEvent, qu'il se manifeste et nous éclaire de sa lanterne, parce que là, je sèche.
Jamais réussi à comprendre comment fonctionne ces deux notions :(

En tout cas, renseigne toi dessus, c'est officiellement la bonne façon de faire, et tu comprendras peut-être mieux que moi :)
 

tototiti2008

XLDnaute Barbatruc
Re : Structure en Arbre n-aire en VBA

Re,

En tout cas merci de tes informations :), probable que je suive ton conseil pour l'appel des évènements, l'aide VBA semble muette sur Inherits ce qui n'est pas bon signe, et il me semblait que les héritages c'était pour des classes ayant des éléments communs mais quelques différences, genre la classe Control qui fait hériter aux Textbox, Listbox, etc..., autant d'enfants qui sont tous des contrôles mais qui ont des propriétés/méthodes spécifiques

A première vue c'est ce qui me semble le plus complexe dans les classes : je suis dans la classe A, comment je fais pour accéder à telle ou telle autre partie....
Je viens à peine de découvrir l'utilisation de Me pour une classe, pourtant indispensable ;), surtout pour définir le Parent
 

Orodreth

XLDnaute Impliqué
Re : Structure en Arbre n-aire en VBA

Je suis pas allé aussi loin pour Excel :))

En fait, en poo, une classe est l'implémentation structurelle et pratique d'un Type, qui lui est un "contrat d'utilisation" (dans un Type, ne sont référencés que les éléments qui sont connus de l'extérieur, et aucun code n'est implémenté).

En héritant de ton Type (ta famille si tu veux), ta classe accepte d'avoir un certain nombre de comportements publics qu'elle rend disponible pour l'extérieur.
Ce qu'elle fait après à l'intérieur d'elle-même (private) ne regarde qu'elle.

Exemple: dans une application de retouche d'image, tu vas avoir différentes sortes de Flou.
Flou est le type, avec lequel tu t'attends à avoir un certain résultat.
Flou gaussion est une classe héritée de Flou qui a son comportement spécifique mais qui renvoie les résultats attendus par le Type Flou.

Par défaut, et à l'origine, tout hérite de la classe OBJECT.
 

tototiti2008

XLDnaute Barbatruc
Re : Structure en Arbre n-aire en VBA

Re,

C'est là qu'il faut commencer à jouer avec des héritages ? je sens le mal de tête arriver ;)

Bon, ça y est, 2 dolipranes et au lit :), Inherits, Implements, Extends, etc... dont la plupart n'existent pas en VBA et qui n'ont pas l'air de s'appliquer aux évènements (ou je n'ai pas vu d'exemple), je capitule
Finalement, très bien ta méthode publique :D
 

tototiti2008

XLDnaute Barbatruc
Re : Structure en Arbre n-aire en VBA

Re,

Oui, oui, je vais finir par le connaître par coeur, excellent tutoriel ;)
Il me semblait simplement que créer des objets imbriqués était l'étape suivante logique, et que forcément l'appel d'évènement de l'objet parent depuis l'objet enfant serait décrit quelque part, à part toi (merci encore), pas trop trouvé d'exemple
 

Orodreth

XLDnaute Impliqué
Re : Structure en Arbre n-aire en VBA

Il me semblait simplement que créer des objets imbriqués était l'étape suivante logique

Oh ... Ouais, je pige mieux ce que tu veux dire ... et donc l'utilisation du doliprane.
Tu t'attaques à des concepts objets qui font mal au crâne quand on connait pas la POO.

Pour ça, je te conseille de suivre des tutoriels sur la Programmation Orientée Objet non exclusifs à Excel, tu comprendras beaucoup mieux les notions.

http://www.loria.fr/~abelaid/Enseignement/FC/Cours5-heritage.pdf <== Bon, c'est du Java (à priori) mais ça reste compréhensible.

Ce dont tu parles en fait, ce sont les notions de redéfinition et de surcharge.
- Redéfinir une méthode héritée, c'est reprendre son nom, sa signature (les paramètres qu'on lui passe, et son éventuel type de retour) et réécrire le code à l'intérieur
- Surcharger une méthode, c'est reprendre le nom de la méthode, changer les paramètres qu'on lui passe, et reprendre le type de retour.

Ca réserve quelques surprises assez spéciales quand on joue avec ...

Je me souviens plus trop comment se fait le code, mais en gros, tu as :
- une classe Nourriture et une classe Herbe qui hérite de Nourriture,
- une classe Animal et une classe Lapin qui hérite de Animal
- une méthode Manger(N as Nourriture) dans Animal, que tu retrouves dans Lapin (puisqu'elle en hérite).
- une méthode Manger(H as Herbe) dans Lapin

En éxécutant le code d'une certaine manière, tu donnes à manger à ton lapin de l'herbe, et il te dit qu'il mange de la nourriture.
C'est assez conceptuel la POO :))
 

Statistiques des forums

Discussions
312 685
Messages
2 090 939
Membres
104 703
dernier inscrit
romla937