cs_EXCLUSIF
Messages postés59Date d'inscriptionmercredi 5 février 2003StatutMembreDernière intervention 9 août 2007
-
20 janv. 2007 à 18:35
cs_EXCLUSIF
Messages postés59Date d'inscriptionmercredi 5 février 2003StatutMembreDerniè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
cs_caramelmou
Messages postés56Date d'inscriptionjeudi 25 décembre 2003StatutMembreDernière intervention23 avril 20083 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
cs_caramelmou
Messages postés56Date d'inscriptionjeudi 25 décembre 2003StatutMembreDernière intervention23 avril 20083 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)
cs_caramelmou
Messages postés56Date d'inscriptionjeudi 25 décembre 2003StatutMembreDernière intervention23 avril 20083 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 ??
cs_caramelmou
Messages postés56Date d'inscriptionjeudi 25 décembre 2003StatutMembreDernière intervention23 avril 20083 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
Vous n’avez pas trouvé la réponse que vous recherchez ?
cs_EXCLUSIF
Messages postés59Date d'inscriptionmercredi 5 février 2003StatutMembreDernière intervention 9 août 20071 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 :'(
cs_EXCLUSIF
Messages postés59Date d'inscriptionmercredi 5 février 2003StatutMembreDernière intervention 9 août 20071 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
-------------------------------------------------------------------------------------------------------------------------
cs_EXCLUSIF
Messages postés59Date d'inscriptionmercredi 5 février 2003StatutMembreDernière intervention 9 août 20071 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.
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