Bonjour,
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 :
- Son premier enfant (Child) (niveau n+1)
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
- Son suivant (Next) (niveau n)
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
- Le suivant de son père (Parent puis Next) (niveau n-1)
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
- Aucun n½ud si on est arrivé à la dernière ligne
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( Split (tvw.Nodes(i).FullPath, tvw.PathSeparator))
MaxNiveau = IIf(MaxNiveau < Niveau, Niveau, MaxNiveau)
Colonnes = UBound( Split (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:
Loop
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