Treeview

hadddock Messages postés 15 Date d'inscription mardi 21 mai 2002 Statut Membre Dernière intervention 26 novembre 2017 - 23 févr. 2008 à 19:59
hadddock Messages postés 15 Date d'inscription mardi 21 mai 2002 Statut Membre Dernière intervention 26 novembre 2017 - 23 mars 2008 à 20:15
Bonjour,
J'ai rempli (en VB6.0.81.76) un treeview avec des données hiérarchisées venant d'une base ACCESS et je souhaiterais balayer l'ensemble de ce treeview de la première à la dernière ligne (pour export vers EXCEL) sans me soucier du niveau hiérarchique de chaque ligne, ce qui n'est pas possible en utilisant la propriété index puisque celle-ci dépend de l'ordre de création des noeuds et de leurs enfants.
Par ailleurs, mon treeview contient environ 40000 lignes et la propriété Nodes.Count devient négative à partir de 32767.

Merci de m'aider

3 réponses

cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
24 févr. 2008 à 02:54
Salut
Version :
VB6.0.81.76
Je suppose qu'il s'agit de la version que tu lis dans les propriétés du fichier VB6.EXE ?
Pour ma part, c'est la 6.0.97.82 qui est la dernière et uiltime version.
Pour te mettre à jour, charge le SP6 de VB6 dispo chez Microsoft.

Problème :
Cela m'étonne que Nodes.Count soit limité à un Integer.
Vérifie si tu n'essayerai pas de stocker ce Count dans une variable dimensionnée en Integer.
Si oui, modifie son type en Long.

Pour sauvegarder le contenu d'un TreeView, il te faudra sauver aussi le lien Parent-Enfant de chaque Node.
A toi d'imaginer une structure de fichier permettant de repérer facilement cet état.
Suffit aussi de chercher "sauver treeview" parmi les codes du site pour avoir des exemples.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

<hr />Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
0
mloriam Messages postés 1 Date d'inscription dimanche 16 juillet 2006 Statut Membre Dernière intervention 23 mars 2008
23 mars 2008 à 08:35
Bonjour,
J'ai le même problème avec un treeview utilisé sous Access. Il semble que l'index soit de type Integer et donc limité à 32767, au delà il prend une valeur négative. Avez-vous trouvé des informations complémentaires sur ce sujet, voir une solution ?.
Merci

Mlab
0
hadddock Messages postés 15 Date d'inscription mardi 21 mai 2002 Statut Membre Dernière intervention 26 novembre 2017
23 mars 2008 à 20:15
Bonjour,<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /??>





D’abord, merci à jack pour le tuyau du SP6.





Ensuite, après recherches, j’ai fini par découvrir que le TreeView ne gérait que des index en Integer : cf. à ce sujet http://support.microsoft.com:80/kb/182231/fr (Microsoft admet qu’il s’agit d’un bug) même si on peut y créer un nombre de nœuds supérieur.





Or mon problème était de balayer les nœuds (environ 45000) de haut en bas, sans me soucier de leur niveau hiérarchique, et de les envoyer dans cet ordre dans les cellules d’un MsFlexGrid ou dans un classeur EXCEL.





Après nombre d’essais infructueux en utilisant des codes source trouvés ici et là (j’avais presque réussi avec http://www.vbfrance.com/codes/SAUVEGARDE-TREEVIEW-ORDRE-SON-CONTENU_39885.aspx mais il y avait un bug dès que plusieurs nœuds étaient rattachés à la racine et il de dépassait pas le seuil des 32767 noeuds).





J’ai donc repris le Pb à zéro et je suis parti des hypothèses suivantes :





En se positionnant sur un nœud quelconque de niveau n, le nœud suivant ne pouvait être que :




<ol style="MARGIN-TOP: 0cm" type="1">
<li class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: justify; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt">
Son premier enfant ( Child ) (niveau n+1)


</li>
</ol>


1.1.   


Il existe, on se positionne dessus et on le récupère







1.2.   


Il n’existe pas (err 91) et on passe au point 2





<ol style ="MARGIN-TOP: 0cm" type= "1" start="2">
<li class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: justify; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt">
Son suivant ( Next ) (niveau n)


</li>
</ol>


2.1.   


Il existe, on se positionne dessus et on le récupère







2.2.   


Il n’existe pas (err 91) et on passe  au point 3





<ol style ="MARGIN-TOP: 0cm" type= "1" start="3">
<li class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: justify; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt">
Le suivant de son père ( Parent puis Next) (niveau n-1)


</li>
</ol>


3.1.   


Il existe, on se positionne dessus et on le récupère







3.2.   


Il n’existe pas (err 91) et on passe au niveau n-2 en recherchant le Parent du Parent puis au point 3







3.3.   


S’il n’y a toujours rien au niveau 0, on est arrivé au point 4





<ol style ="MARGIN-TOP: 0cm" type= "1" start="4">
<li class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: justify; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt">
Aucun nœud si on est arrivé à la dernière ligne


</li>
</ol>

Il suffisait donc de se positionner sur le premier nœud et de faire une boucle jusqu’à arriver au point 4.





Le principal Pb était que la non-existence d’un nœud se traduisait toujours par la même erreur 91 et qu’il fallait trouver une astuce pour détecter son origine.





Je pense y être à peu près arrivé avec le code ci-dessous qui remplit les 45000 lignes du MsFlexGrid en moins d’une minute. Attention : si le nombre de nœuds est supérieur à 32767, la propriété Nodes.Count provoque une erreur et il faut utiliser la fonction SendMessage.





Bon courage !







Hadddock

 






Private Const TVM_GETCOUNT = &H1105&







Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long








 






Private Sub Sequence(tvw As TreeView)






    On Error GoTo erreur






    Dim Remonter As Byte






   

Dim Niveau As Byte






    Dim Colonnes As Byte






   

Dim MaxNiveau As Byte






    Dim MaxCol As Byte






    Dim i as Long






    Screen.MousePointer = vbHourglass






   

tvw.Visible = False






    MSFlexGrid1.Visible = False






    MSFlexGrid1.Rows = 1  

‘ réservé pour un en-tête










    For i = 1 To SendMessage(tvw.hwnd, TVM_GETCOUNT, 0, ByVal 0)

' recherche du niveau et du nombre de colonnes maximum










       

Niveau = UBound(
<?xml:namespace prefix st1 ns "urn:schemas-microsoft-com:office:smarttags" /??>
<st1:city>
<st1:place>
Split
</st1:place>
</st1:city>
(tvw.Nodes(i).FullPath, tvw.PathSeparator))






       

MaxNiveau = IIf(MaxNiveau < Niveau, Niveau, MaxNiveau)






       

Colonnes = UBound(
<st1:city>
<st1:place>
Split
</st1:place>
</st1:city>
(tvw.Nodes(i).Text, Chr(9))) + 1






       

MaxCol = IIf(MaxCol < Colonnes, Colonnes, MaxCol)






    Next i









    MSFlexGrid1.Cols = MaxCol






    tvw.Nodes(1).Root.Selected = True

‘ se positionne sur le premier noeud










    MSFlexGrid1.AddItem tvw.SelectedItem.Text






   

Do





RechercheEnfant:






        Recherche = "enfant"






        tvw.SelectedItem.Child.Selected = True

‘ s’il n’existe pas renvoie une erreur 91










        MSFlexGrid1.AddItem tvw.SelectedItem.Text

‘ s’il existe l’envoie dans la grille










        GoTo suite





RechercheSuivant:






        Recherche = "suivant"






        tvw.SelectedItem.Next.Selected = True

‘ s’il n’existe pas renvoie une erreur 91










        MSFlexGrid1.AddItem tvw.SelectedItem.Text

‘ s’il existe l’envoie dans la grille










        GoTo suite





RechercheParent:






        Recherche = "parent"






        tvw.SelectedItem.Parent.Selected = True

‘ existe forcément puisqu’appelé par un de ses enfants










        tvw.SelectedItem.Next.Selected = True

‘ s’il n’existe pas renvoie une erreur 91










        MSFlexGrid1.AddItem TreeView1.SelectedItem.Text

‘ s’il existe l’envoie dans la grille










        Remonter = 0





suite:






   

<st1:place>
Loop
</st1:place>








erreur:






    Select Case Err






    Case 91






       

If Recherche = "enfant" Then Resume RechercheSuivant 

'   pas d'enfant > recherche du suivant










        If Recherche = "suivant" Then Resume RechercheParent 

'   pas de suivant > recherche du parent puis de son suivant










        If Recherche = "parent" Then 

'   pas de suivant au parent > recherche du parent au niveau inférieur










            Remonter = Remonter + 1






            If Remonter > MaxNiveau Then 

'   pas de parent au niveau le plus bas > sortie










               

tvw.Visible = True






                MSFlexGrid1.Visible = True






                Screen.MousePointer = vbArrow






               

Exit Sub






            Else






                Resume RechercheParent

' recherche du parent de niveau inférieur










           

End If






        End If






    Case Else






       

MsgBox ("Erreur " & Err & " : " & Err.Description)






       

Resume Next






    End Select





End Sub






 







 
0
Rejoignez-nous