Chargement Treeview à partir d'une base access

Résolu
cs_EXCLUSIF Messages postés 59 Date d'inscription mercredi 5 février 2003 Statut Membre Dernière intervention 9 août 2007 - 20 janv. 2007 à 18:35
cs_EXCLUSIF Messages postés 59 Date d'inscription mercredi 5 février 2003 Statut Membre Dernière intervention 9 août 2007 - 22 janv. 2007 à 21:55
Bonjour à tous,


Je fais appel à vous encore une fois car je suis totalement perdu.


Je m'explique, j'ai une base de données et je voudrais charger une
table sous forme de treeview en ADO. Mais ça coince ! Je n'y arrive pas
du tout.


Voici ma table au format access:


IdCategorie (numérique)

NomCategorie (texte)

AnnotationCategorie (memo)

ParentCategorie (numérique) 'indique l'Id de la catégorie Parent (-1 si pas de parent)

NiveauCategorie (numérique) 'indique le niveau (1 puis 2 puis 3....)


J'ai commencé à coder ça mais je ne sais pas comment m'y prendre. La récursivité et moi ça fait 2 on dirait :(

PrivateSub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)HandlesMyBase.Load
Dim i AsInteger
Dim NiveauMaximum AsInteger
 
'connexion à la base de données
db.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & My.Application.Info.DirectoryPath & "\Database\documentalis.mdb" & ";User Id=admin;Password=;"
db.Open()
 
rs.Open("SELECT NiveauCategorie FROM T_Categorie", db, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic)
NiveauMaximum = 0
WhileNot rs.EOF
If(NiveauMaximum < rs.Fields(0).Value)Then NiveauMaximum = rs.Fields(0).Value
rs.MoveNext()
EndWhile
'NiveauMaximum contient le plus grand niveau
rs.Close()
 
rs.Open("SELECT * FROM T_Categorie WHERE NiveauCategorie=1", db, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic)
 
Dim tvRoot As TreeNode
Dim tvNode As TreeNode
Dim strNomCategorie AsString = ""
Dim intIdCategorie AsInteger
 
 
tvRoot = Me.TreeView1.Nodes.Add("Catégories")
 
WhileNot rs.EOF
'chargement des catégories
intIdCategorie = rs.Fields(0).Value'récup de l'id de la catégorie
strNomCategorie = rs.Fields(1).Value'récup du nom de la catégorie
tvNode = tvRoot.Nodes.Add(strNomCategorie)'Ajout du nom de la catégorie
 
For i = 2To NiveauMaximum
 
rs2.Open("SELECT * FROM T_Categorie WHERE NiveauCategorie=" & i & " AND ParentCategorie=" & intIdCategorie, db, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic)
 
 
rs2.Close()
Next
 
rs.MoveNext()'on passe à l'enregistrement suivant
EndWhile
 
rs.Close()
 
 
EndSub


Merci beaucoup pour votre aide

eXclusif

10 réponses

cs_caramelmou Messages postés 56 Date d'inscription jeudi 25 décembre 2003 Statut Membre Dernière intervention 23 avril 2008 3
21 janv. 2007 à 10:38
Bah ça progresse ....
Tu n'as pas besoin de te servir de ce NiveauCategorie ! (ce n'est pas une technique recursive et je te conseille
de supprimer ce champ, à moins qu'il soit independant du niveau de hierarchie dans l'arborescence logique de ta table)

Ta function recursive GenererNoeud doit passer en revue tous les enfants de la categorie passer en parametre
(ici tu n'en traite q'un) et tu dois ajouter le nouveau noeud au noeud parent que tu passe en parametre


Qqchose comme    # treeView1.Nodes(categorie_parent).Nodes.Add( New TreeNode(categorie_fils))  #
(De mémoire parce c'est le WE)

ex: generer_noeud(id_cat, myNode)
           
       ' une boucle pour rechercher les categorie id_fils qui ont id_cat comme parent dans la table
            pour chaque id_fils, on cree un nouveau noeud tmp_node qu'on ajoute comme fils au node MyNode
            et on appelle generer_noeud (id_fils, tmp_node)
      ' fin de la boucle


Normalement ton seul appel de function après avoir crée la racine tvRoot c'est
generer_noeud (-1,tvRoot)  et ça remplit ton treeview

bon WE

Dr.T





Dr.T
3
cs_caramelmou Messages postés 56 Date d'inscription jeudi 25 décembre 2003 Statut Membre Dernière intervention 23 avril 2008 3
21 janv. 2007 à 20:25
Comme ça, ça semble correct coté algorithme.
Je ne peux pas faire de test d'ici sous dot.net, je regarde demain. En attendant, tu peux peut être
verifier que ta fonction generer_noeud parcourt correctement tous les elements de ta table categorie
(sans créer les noeuds), juste en imprimant les categories trouvées.
Il se pourrait qu'une boucle se forme quelque part lors du parcours si quelque part
par erreur un des element se trouvait être l'enfant de son enfant (même indirectement)
ce qui expliquerait que ça 'tourne dans le vide'
C'est le risque des procédures récursives !

Sinon, j'utiliserai plutôt le add surcharge
TreeNodeCollection.Add (String, String)
qui crée un nouveau nœud d'arbre avec la clé et le texte spécifiés, et l'ajoute à la collection.
en mettant comme clef  l'id_cat (plutot que dans le tag)
 en plus en faisant comme ça tu sauras tout de suite si tu essaie d'ajouter plusieurs fois le meme
noeud: comme la clef est la même, ca va bugger au lieu de tourner en rond (les clef devant être uniques)

Bon courage, et si tu bloques toujours , à demain

Dr.T
3
cs_caramelmou Messages postés 56 Date d'inscription jeudi 25 décembre 2003 Statut Membre Dernière intervention 23 avril 2008 3
22 janv. 2007 à 12:21
Pardon mais
        rs3.Open("SELECT * FROM T_Categorie WHERE ParentCategorie=" & IdCat, db, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic)
        While Not rs3.EOF
            intIdCategorie = rs3.Fields(0).Value
            strNomCategorie = rs3.Fields(1).Value 'récup du nom de la catégorie
            tvNode = myNode.Nodes.Add(intIdCategorie, strNomCategorie) 'Ajout du nom de la catégorie
            tvNode.Tag = "C" & intIdCategorie
            GénérerNoeud(intIdCategorie, tvNode)
        End While

ça tourne forcement en rond s'il n'y a pas un movenext qqpart, non ??

Dr.T
3
cs_caramelmou Messages postés 56 Date d'inscription jeudi 25 décembre 2003 Statut Membre Dernière intervention 23 avril 2008 3
20 janv. 2007 à 20:03
Bah oui, tu as un ptit problème avec la récursivite
Pour te donner un objet de réflexion : à quoi sert ton champ
 niveau categorie (à priori à rien, car si tu pars d'un element
qq et que tu remonte à son parent,  tu auras son niveau en comptant le nombre d'opérations)

Essaie déjà de faire une petite procedure recursive pour trouver le niveau.
elle pourra te servir pour gérer ton treeview (trouver le niveau d'un element pour definir son icone dans le treeview par ex)
par ex
Function find_level(id, nb_op) As Long
   If id <> -1 Then
      p_id = find_parent(id)            '  find_parent c'est juste une requete SQL a traiter
      nb_op = find_level(p_id, nb_op + 1)
   End If
   find_level = nb_op
End Function

En suite essaie de faire une procedure pour parcourir tes données de façon récursive
(un peu plus complique, mais pas beaucoup) quand tu l'auras, tu auras gagné..

pour t'orienter: tu crées une fonction display_node(node), et pour chaque enfant de ce node
que ta function va trouver, tu appelle la fonction display_node pour cet enfant.
Il te suffit de commencer par le premier element (parent=-1)
Simple, non  :p

Sinon pour le treeview lui meme, comme je suppose que idCategorie est ta clef primaire,
 n'oublie pas de donner cette valeur comme clef de l'element du treeview, ça te facilitera
la gestion , puisque j'espere que tu créeras , deplaceras, insereras ensuite de nouvelles
categories à partir de ce  treeview  ;-)

Dr.T
1

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_EXCLUSIF Messages postés 59 Date d'inscription mercredi 5 février 2003 Statut Membre Dernière intervention 9 août 2007 1
21 janv. 2007 à 19:31
Voici ma dernière version :

    Public Sub GénérerNoeud(ByVal IdCat As Integer, ByVal myNode As TreeNode)
        Dim tvNode As TreeNode
        Dim intIdCategorie As Integer
        Dim strNomCategorie As String = ""
        Dim rs As New ADODB.Recordset

        rs.Open("SELECT * FROM T_Categorie WHERE ParentCategorie=" & IdCat, db, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic)
        While Not rs.EOF
            intIdCategorie = rs.Fields(0).Value
            strNomCategorie = rs.Fields(1).Value 'récup du nom de la catégorie
            tvNode = myNode.Nodes.Add(strNomCategorie) 'Ajout du nom de la catégorie
            tvNode.Tag = "C" & intIdCategorie
            GénérerNoeud(intIdCategorie, tvNode)
        End While
        rs.Close()
    End Sub

Mais ça ne foncionne toujours pas :(
L'interface n'apparaît même plus comme si ça tournait dans le vide.

Caramelmou je sais que j'abuse mais peux-tu me dire ce qui ne va pas exactement car là je craque. Surtout que ce programme je dois le faire pour des amis médecins et ça la fout mal si j'y arrive pas :'(

Merci bien

eXclusif
1
cs_EXCLUSIF Messages postés 59 Date d'inscription mercredi 5 février 2003 Statut Membre Dernière intervention 9 août 2007 1
20 janv. 2007 à 21:56
Merci pour ces précieux conseils :)

Je vais tester tout ça demain et je te tiens au courant.

eXclusif
0
cs_EXCLUSIF Messages postés 59 Date d'inscription mercredi 5 février 2003 Statut Membre Dernière intervention 9 août 2007 1
21 janv. 2007 à 01:16
Voici ce que j'ai fait mais ça ne fonctionne pas. Je ne sais pas comme insérer mes noeuds enfants dans mon treeview. Caramelmou pourrais-tu me dire comment faire stp ?
----------------------------------------------------------------------------------------------------------------
Public Class Form1

    Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        db.Close()
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Dim i As Integer
        'Dim NiveauMaximum As Integer

        'connexion à la base de données
        db.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & My.Application.Info.DirectoryPath & "\Database\documentalis.mdb" & ";User Id=admin;Password=;"
        db.Open()

        'rs.Open("SELECT NiveauCategorie FROM T_Categorie", db, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic)
        'NiveauMaximum = 0
        'While Not rs.EOF
        '    If (NiveauMaximum < rs.Fields(0).Value) Then NiveauMaximum = rs.Fields(0).Value
        '    rs.MoveNext()
        'End While
        ''NiveauMaximum contient le plus grand niveau
        'rs.Close()

        rs.Open("SELECT * FROM T_Categorie WHERE NiveauCategorie=1", db, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic)

        Dim tvRoot As TreeNode
        Dim tvNode As TreeNode
        Dim strNomCategorie As String = ""
        Dim intIdCategorie As Integer

        tvRoot = Me.TreeView1.Nodes.Add("Catégories")

        While Not rs.EOF
            'chargement des catégories
            intIdCategorie = rs.Fields(0).Value 'récup de l'id de la catégorie
            strNomCategorie = rs.Fields(1).Value 'récup du nom de la catégorie
            tvNode = tvRoot.Nodes.Add(strNomCategorie) 'Ajout du nom de la catégorie
            tvNode.Tag = "C" & intIdCategorie
            GénérerNoeud(intIdCategorie)
            rs.MoveNext() 'on passe à l'enregistrement suivant
        End While

        rs.Close()

    End Sub

    Public Sub GénérerNoeud(ByVal NodeParent As Integer)
        Dim tvNode As TreeNode
        Dim intIdCategorie As Integer
        Dim strNomCategorie As String = ""

        rs.Open("SELECT * FROM T_Categorie WHERE ParentCategorie=" & NodeParent, db, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic)
        intIdCategorie = rs.Fields(0).Value
        strNomCategorie = rs.Fields(1).Value 'récup du nom de la catégorie
        tvNode = Me.TreeView1.Nodes.Add(strNomCategorie) 'Ajout du nom de la catégorie
        tvNode.Tag = "C" & intIdCategorie
        rs.Close()
        GénérerNoeud(intIdCategorie)
    End Sub

End Class
-------------------------------------------------------------------------------------------------------------------------

eXclusif
0
cs_EXCLUSIF Messages postés 59 Date d'inscription mercredi 5 février 2003 Statut Membre Dernière intervention 9 août 2007 1
21 janv. 2007 à 12:31
Merci pour les compliments !

Ca progresse, certes ! Mais c'est pas encore ça !
Mon NiveauCategorie je le garde pour l'instant même si je ne m'en sers plus du tout. Du moins pour l'instant. Peut-être me servira t'il pour effectuer des requêtes sur ma base.

Merci encore une fois pour ton aide si précieuse. Je vais tester tout ça cet après-midi et j'espère y arriver.

Je te tiens au courant ;-)

eXclusif
0
cs_EXCLUSIF Messages postés 59 Date d'inscription mercredi 5 février 2003 Statut Membre Dernière intervention 9 août 2007 1
21 janv. 2007 à 21:12
J'y comprends plus rien. J'ai surchargé le add mais ça plante pas. Le processus tourne à 80 voire 90% et rien ne se passe.

Je te fais une copie de mon code en entier car si ça se trouve l'erreur vient d'ailleurs.

----------------------------------------------------------------------------------------------

Public Class Form1

    Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        db.Close()
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'connexion à la base de données
        db.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & My.Application.Info.DirectoryPath & "\Database\documentalis.mdb" & ";User Id=admin;Password=;"
        db.Open()

        rs.Open("SELECT * FROM T_Categorie WHERE NiveauCategorie=1", db, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic)

        Dim tvRoot As TreeNode
        Dim tvNode As TreeNode
        Dim strNomCategorie As String = ""
        Dim intIdCategorie As Integer

        tvRoot = Me.TreeView1.Nodes.Add("Catégories")

        While Not rs.EOF
            'chargement des catégories
            intIdCategorie = rs.Fields(0).Value 'récup de l'id de la catégorie
            strNomCategorie = rs.Fields(1).Value 'récup du nom de la catégorie
            tvNode = tvRoot.Nodes.Add(strNomCategorie) 'Ajout du nom de la catégorie
            tvNode.Tag = "C" & intIdCategorie
            GénérerNoeud(intIdCategorie, tvNode)
            rs.MoveNext() 'on passe à l'enregistrement suivant
        End While
        rs.Close()
    End Sub

    Public Sub GénérerNoeud(ByVal IdCat As Integer, ByVal myNode As TreeNode)
        Dim tvNode As TreeNode
        Dim intIdCategorie As Integer
        Dim strNomCategorie As String = ""
        Dim rs3 As New ADODB.Recordset

        rs3.Open("SELECT * FROM T_Categorie WHERE ParentCategorie=" & IdCat, db, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic)
        While Not rs3.EOF
            intIdCategorie = rs3.Fields(0).Value
            strNomCategorie = rs3.Fields(1).Value 'récup du nom de la catégorie
            tvNode = myNode.Nodes.Add(intIdCategorie, strNomCategorie) 'Ajout du nom de la catégorie
            tvNode.Tag = "C" & intIdCategorie
            GénérerNoeud(intIdCategorie, tvNode)
        End While
        rs3.Close()
    End Sub

End Class

----------------------------------------------------------------------------------------------

Le contenu de ma table CATEGORIE pour l'instant est le suivant :

IdCategorie | NomCategorie | AnnotationCategorie | ParentCategorie | NiveauCategorie
       0          |    Cardiologie   |                                 |            -1           |             1
       1          |   Dermatologie |                                 |            -1           |             1
       2          |        Divers       |                                 |            -1           |             1
       3          |     Esthétique    |                                 |              1           |             2

Et voici ce que je veux obtenir... mais que je ne suis pas fichu d'arriver à faire

-Catégorie
            |____Cardiologie
            |
            |____Dermatologie
            |                        |_Esthétique
            |
            |____Divers

Je te remercie pour ta patience en tout cas !

eXclusif
0
cs_EXCLUSIF Messages postés 59 Date d'inscription mercredi 5 février 2003 Statut Membre Dernière intervention 9 août 2007 1
22 janv. 2007 à 21:55
C'est parfait tu as mis le doigt sur mon erreur ! Ca fonctionne à merveille maintenant !!!

Merci beaucoup Caramelmou !!!

eXclusif
0
Rejoignez-nous