Bonjour,

Depuis quelques jours, je suis confronté au problèmes suivant: je dois remplir un TTreeView (tvNMOnglets_ong1_arbre, dans la form frmNoteManagementMainWindow) de façon ordonnées depuis les données récuperées d'une base de données SQL.

voici donc la table sql :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
 
CREATE TABLE Tbl_Branche (
	Bra_IDBranche INTEGER NOT NULL,
	Bra_BraPere INTEGER,
	Bra_Cat_IDCategorie INTEGER NOT NULL,
	Bra_nom VARCHAR (24) NOT NULL
	)
;
et voici donc le code pour créer les premiers noeuds:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
 
procedure CreerNoeud(i_idOngSelect:INTEGER);
  var
    i_IDFils, i_IDNoeud : INTEGER;
    i_NoeudTotal :string;
    s_NomNoeud, s_NULL : string;
 
  begin
  //s_NULL := 'NULL';
  dmNoteManagement.dstmemNMNotes.Active:=FALSE;
  dmNoteManagement.dstmemNMNotes.CommandText := 'SELECT COUNT(bra_IDBranche) AS "Total Branche", bra_IDBranche from tbl_Branche where bra_cat_IDCategorie = '+IntToStr(i_idOngSelect)+' AND bra_braPere IS NULL GROUP BY Bra_IDBranche';
  //InputBox('','',dmNoteManagement.dstmemNMNotes.CommandText);
  dmNoteManagement.dstmemNMNotes.Active:=TRUE;
  //compteur qui indique le nombre total de noeud a créer
  i_NoeudTotal := dmNoteManagement.dstmemNMNotes.FieldByName('Total branche').AsString;
  //si null ou 0 (j'ai ici un doute quand a la valeur que sql retourne...'NULL' ou 0 ? :s
  IF (i_NoeudTotal <> 'NULL') and (i_NoeudTotal <> '0') THEN
    begin
      dmNoteManagement.ADODataSet1.Active:=FALSE;
      dmNoteManagement.ADODataSet1.CommandText := 'SELECT bra_nom FROM tbl_Branche where bra_cat_IDCategorie = '+IntToStr(i_idOngSelect)+'AND bra_braPere IS NULL';
      InputBox('','',dmNoteManagement.ADODataSet1.CommandText);
      dmNoteManagement.ADODataSet1.Active:=TRUE;
      dmNoteManagement.ADODataSet1.First;
      while (dmNoteManagement.ADODataSet1.Eof = false) do
        begin
          s_NomNoeud := dmNoteManagement.ADODataSet1.FieldByName('bra_nom').AsString;
        //voila le début des problèmes, il faut que j'ajoute les premiers noeud, jusque la pas de problème, mais sa va venir plus tard ! Je ne sais pas quel fonction utiliser pour lui dire que c'est les premiers noeuds (.TopItem est correcte ?)
frmNoteManagementMainWindow.tvNMOnglets_ong1_arbre.Items.Add(frmNoteManagementMainWindow.tvNMOnglets_ong1_arbre.TopItem,s_NomNoeud);
          //ici je fais un .focused car je veux qu'il se mette sur celui que je créer pour créer plus tard les fils grace a la commande .items.selected
          frmNoteManagementMainWindow.tvNMOnglets_ong1_arbre.Focused;
          frmNoteManagementMainWindow.tvNMOnglets_ong1_arbre.Refresh;
          dmNoteManagement.ADODataSet1.Active:=FALSE;
          dmNoteManagement.ADODataSet1.CommandText:= 'SELECT bra_IDBranche from tbl_Branche WHERE bra_nom = '''+s_NomNoeud+'''';
          dmNoteManagement.ADODataSet1.Active:=TRUE;
          i_IDNoeud := dmNoteManagement.ADODataSet1.FieldByName('bra_IDBranche').Value;
          dmNoteManagement.ADODataSet1.Active:=FALSE;
          dmNoteManagement.ADODataSet1.CommandText:= 'SELECT bra_IDBranche from tbl_Branche WHERE bra_BraPere = '''+IntToStr(i_IDNoeud)+'''';
          dmNoteManagement.ADODataSet1.Active:=TRUE;
          dmNoteManagement.ADODataSet1.First;
          //boucle qui va creer les fils.
          while (dmNoteManagement.ADODataSet1.Eof = False) do
            begin
              i_IDFils:= dmNoteManagement.ADODataSet1.FieldByName('bra_IDBranche').AsInteger;
              proc_CreerFils.CreerFils(i_IDFils);
              dmNoteManagement.ADODataSet1.Next;
            end;
          dmNoteManagement.ADODataSet1.Next;
        end;
  end;
 
end.

Et maintenent le code pour creer les fils:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
  procedure CreerFils(i_IDFils: INTEGER);
  var
    i_PereID, i_filsID: INTEGER;
    s_nomFils: String;
  begin
 
    dmNoteManagement.dstCreerFils.Active:=FALSE;
    dmNoteManagement.dstCreerFils.CommandText:='SELECT bra_nom FROM tbl_branche WHERE bra_IDBranche = '+IntToStr(i_IDFils);
    dmNoteManagement.dstCreerFils.Active:=TRUE;
    s_nomFils := dmNoteManagement.dstCreerFils.FieldByName('bra_nom').AsString;
    //premier probleme ici : il ne se mets pas sur la selection de celui qu'il vient de créer, et donc ne creer pas le noeud en tant que 'fils' (.AddChild), il les créers donc à la suite
   frmNoteManagementMainWindow.tvNMOnglets_ong1_arbre.Items.AddChild(frmNoteManagementMainWindow.tvNMOnglets_ong1_arbre.Selected,s_nomFils);
    frmNoteManagementMainWindow.tvNMOnglets_ong1_arbre.Refresh;
    dmNoteManagement.dstCreerFils.Active:=FALSE;
    dmNoteManagement.dstCreerFils.CommandText:='SELECT bra_IDBranche FROM tbl_Branche where bra_BraPere = '+IntToStr(i_IDFils);
    dmNoteManagement.dstCreerFils.Active:=TRUE;
 
    dmNoteManagement.dstCreerFils.First;
    //ici il verifie avec la selection du fils creer si il a lui meme des fils, si oui, il rentre dans la boucle et s'appele lui même.
    while (dmNoteManagement.dstCreerFils.Eof=FALSE) do
      begin
        i_filsID:= dmNoteManagement.dstCreerFils.FieldByName('bra_IDBranche').Value;
        proc_CreerFils.CreerFils(i_filsID);
        dmNoteManagement.dstCreerFils.Next;
      end;
 
  end;

Et les jeux de tests:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
 
----------------------------------------------------------------------------------------------------
--Insertion dans la table Tbl_Branche
----------------------------------------------------------------------------------------------------
INSERT INTO Tbl_Branche VALUES (0,NULL,0, 'Test0');
INSERT INTO Tbl_Branche VALUES (1,0,1, 'Test1');
INSERT INTO Tbl_Branche VALUES (2,0,2, 'Test2');
INSERT INTO Tbl_Branche VALUES (3,1,3, 'Test3');
INSERT INTO Tbl_Branche VALUES (4,1,4, 'Test4');
INSERT INTO Tbl_Branche VALUES (5,3,5, 'Test5');
INSERT INTO Tbl_Branche VALUES (6,5,6, 'Test6');
INSERT INTO Tbl_Branche VALUES (7,6,7, 'Test7');

Voilà mon problème est donc de gerer l'affichage correcte de l'arbre. Comme solution je pense que sa doit surement être la recusivité, mais mon problème previent:
1: des fonctions pour creer les premiers noeuds et les enfants (je n'utilise surmenent pas correctement toutes les procedures préfabricant
2: mon algo doit avoir des défaillances, mais je n'arrive pas à les voirs


J'ai cherché un peu sur le net, rien trouvé, ou alors j'ai mal cherché... voilà sa fait environ 3 jours que je suis bloqué la dessus. Une petite aide serait bien venue. Si nécessaire, je donne volontiers les fichiers sources

ps: j'utilise actuellement delphi 7

Merci beaucoup et bonne journée !