IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

Remplissage récursif d'un treeview.


Sujet :

Delphi

  1. #1
    Membre habitué

    Profil pro
    Inscrit en
    Février 2005
    Messages
    317
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 317
    Points : 183
    Points
    183
    Par défaut Remplissage récursif d'un treeview.
    Bonjour, j'ai une table qui se présente de la sorteexemple)

    +-----------------------+
    |champ1|champ2|champ3|
    +-----------------------+
    |valeur1 |valeur1 |valeur1|
    |valeur1 |valeur1 |valeur2|
    |valeur1 |valeur1 |valeur3|
    |valeur1 |valeur2 |valeur1|
    |valeur1 |valeur2 |valeur2|
    |valeur1 |valeur2 |valeur3|
    |valeur2 |valeur1 |valeur1|
    |valeur2 |valeur1 |valeur2|
    |valeur2 |valeur1 |valeur3|
    |valeur2 |valeur2 |valeur1|
    |valeur2 |valeur2 |valeur2|
    |valeur2 |valeur2 |valeur3|
    ...
    J'aimerai donc a partir de cette table génerer un treeview de la sorte:

    root
    |__valeur1
    | |__valeur1
    | | |___valeur1
    | | |___valeur2
    | | |___valeur3
    | |
    | |__valeur2
    | |___valeur1
    | |___valeur2
    | |___valeur3
    |
    |__valeur2
    | |__valeur1
    | | |___valeur1
    | | |___valeur2
    | | |___valeur3
    | |
    | |__valeur2
    | |___valeur1
    | |___valeur2
    | |___valeur3

    Bon j'espère que c'est assez clair: J'ai fait une fonction récursive, dont je vous donne le code:
    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
     
    procedure TForm1.loaddb();
    Const
    pref_geo='GEO$';
    var i : integer;
    Paysli, Oli :TTreeNode;
    fields:tstringlist;
    fieldsG:tstringlist;
    pkf:string;
    begin
    treefields.Items.Clear;
    treecust.Items.Clear;
    fieldsyears:='';
    fields:=tstringlist.Create;
    fieldsG:=tstringlist.Create;
     
    if length(cmbtables.Text) <1 then exit;
     
     pkf:=getpk(cmbtables.Text); //clef primaire de la table
    paysli:=treefields.Items.Add(nil,'Pays');
    Oli:=treefields.Items.Add(nil,'Paramètres');
     
      UIBQuery.SQL.Clear;
      UIBQuery.SQL.Add('SELECT * FROM "' + cmbtables.Text + '";');
      UIBQuery.Open;
     
     
      for i := 0 to UIBQuery.Fields.FieldCount - 1 do
      begin
            if(lowercase(pkf) <> lowercase(UIBQuery.Fields.SqlName[i])) then
      	begin
      	if(not isnumeric(UIBQuery.Fields.SqlName[i])) then
            	if(leftstr(UPPERCase(UIBQuery.Fields.SqlName[i]),length(pref_geo))=pref_geo) then  //je veux séparer les champs commençant par pref_geo a part...
      	        	fieldsG.add(UIBQuery.Fields.SqlName[i])
                    else
                            fields.add(UIBQuery.Fields.SqlName[i])
     	 else begin
             	fieldsyears:=fieldsyears+ ',SUM("' + UIBQuery.Fields.SqlName[i] +'") as "' + UIBQuery.Fields.SqlName[i] +'"';
                	fieldsyears2:=fieldsyears2+ ',"' + UIBQuery.Fields.SqlName[i] +'"';
      	end;
            end;
      end;
     
    UIBQUERY.close();
    treefields.items.BeginUpdate;
    recfields(fieldsG,paysli);
    recfields(fields,Oli);
    treefields.items.endUpdate;
     
    end;
    Et la fonction récursive:
    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 tform1.recfields(fields : tstringlist;  item : TTreeNode);
    var
    titem : TTreeNode;
    tf:tstringlist;
    i:integer;
    begin
    if not (fields.Count>0) then exit;
     
     
    UIBQuery.SQL.Clear;
    UIBQuery.SQL.Add('SELECT DISTINCT "' + fields[0] + '" FROM "' + cmbtables.Text + '";');
    UIBQuery.Open;
    tf:=TStringList.Create;
    fields.Delete(0);
    while not UIBQuery.EOF do
    begin
        tf.Add(UIBQuery.Fields.AsString[0]);
        UIBQuery.Next;
    end;
    UIBQuery.Close();
    for i := 0 to tf.Count - 1 do
    begin
        titem:=treefields.Items.AddChild(item,tf.Strings[i]);
        recfields(fields,titem);
    end;
    tf.free;
    end;

    Seulement, ça ne marche pas, j'ai que le premier champ qui est rempli :s
    Je vais chercher de mon coté, mais si quelqu'un pouvait m'aider, je galère un peu avec les treeviews...
    Merci d'avance!

  2. #2
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Voici un ensemble de procédure qui permettent de faire ce que tu veux, j'ai retrouvé çà dans un vieux code donc c'est perfectible

    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
     
    var
      FieldList: TStringList;
     
    ...
     
    procedure TfrmMain.FillTree;
    begin
      With ModuleDonnees do
      begin
        FieldList := TStringList.create;
        TreeView1.Items.Clear;;
        TreeView1.items.BeginUpdate;
        LeQuery.first;
        while not LeQuery.eof do
        begin
           TreeAddItem(TreeView1, GetFieldList, LeQuery.getBookmark, false);
           LeQuery.next;
      end;
      FieldList.clear;
      TreeView1.items.Endupdate;
      fieldList.free;
    end;
     
    // Le query a un truc du style
    // select champ1,Champ2,Champ3 from latable
    // order by champ1,champ2,champ3
    function TfrmMain.GetFieldList: TStringList;
    begin
      With ModuleDonnees do
      begin
        FieldList.clear;
        FieldList.add(LeQuery.fieldbyname('Champ1').asstring);
        FieldList.add(LeQuery.fieldbyname('Champ2').asstring);
        FieldList.add(LeQuery.fieldbyname('Champ3').asstring);
        Result := FieldList;
      end;
    end;
     
    function TfrmMain.TreeAddItem(Sender: TTreeView; ItemList: TStrings; Bookmark: TBookmark; Resort: Boolean): TTreeNode;
    var
       ThisNode, Node: TTreeNode;
       I: Integer;
    begin
         Node := nil;   //nil = level 0 has no parent node
                        //this is checked by TreeFindItem
         for I := 0 to Itemlist.count -1 do
         begin
              ThisNode := TreeFindItem(Sender, node, Itemlist[i]);
              if ThisNode <> nil then Node := ThisNode else
              begin
                   if I < Itemlist.count -1 then
                   begin
                        if I = 0 then Node := Sender.items.AddObject(Node, Itemlist[i],Bookmark)
                        else Node := Sender.items.AddChildObject(Node, Itemlist[i], BookMark);
                   end else
                   begin
                        if I = 0 then Node := Sender.items.AddObject(Node, Itemlist[i], Bookmark)
                        else Node := Sender.items.AddChildObject(Node, Itemlist[i], Bookmark);
                   end;
                   Node.stateIndex := Node.level + 1;
                   if Resort and (Node.parent <> nil) then Node.parent.alphasort; 
              end;
         end;
         Result := Node;
    end;
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  3. #3
    Membre habitué

    Profil pro
    Inscrit en
    Février 2005
    Messages
    317
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 317
    Points : 183
    Points
    183
    Par défaut
    En fait ça venait des tstringlist en paramètres, l'algo était bon :s
    VOici le code corrigé:
    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
     
     
    procedure tform1.recfields(fields :array of string;  item : TTreeNode);
    var
    titem : TTreeNode;
    tf:tstringlist;
    tfields : array of string;
    i:integer;
    begin
     
    if not (length(fields)>0) then exit;
     
    UIBQuery.SQL.Clear;
    UIBQuery.SQL.Add('SELECT DISTINCT "' + fields[0] + '" FROM "' + cmbtables.Text + '";');
    UIBQuery.Open;
    tf:=TStringList.Create;
     
    setlength(tfields,length(fields)-1);
    for i := 1 to length(fields)-1 do
           tfields[i-1]:=fields[i];  //on enlève le premier
     
     
    while not UIBQuery.EOF do
    begin
        tf.Add(UIBQuery.Fields.AsString[0]);
        UIBQuery.Next;
    end;
    UIBQuery.Close();
    for i := 0 to tf.Count - 1 do
    begin
        titem:=treefields.Items.AddChild(item,tf.Strings[i]);
        recfields(tfields,titem);
    end;
    tf.free;
    setlength(tfields,0);
    end;

  4. #4
    Membre actif Avatar de liazidf
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations forums :
    Inscription : Mai 2002
    Messages : 281
    Points : 261
    Points
    261
    Par défaut Remplissage du treeview
    Votre exemples est interessant, mais il fait appel à la function TreeFindItem qui n'est définie nul part.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    for I := 0 to Itemlist.count -1 do
         begin
              ThisNode := TreeFindItem(Sender, node, Itemlist[i]);
              if ThisNode <> nil then Node := ThisNode else
              begin
                   if I < Itemlist.count -1 then
                   begin
                        if I = 0 then Node := Sender.items.AddObject(Node, Itemlist[i],Bookmark)

  5. #5
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    voici la fonction manquante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    function TreeFindItem(Sender: TTreeView; NodeItem: TTreeNode; Name: String): TTreeNode;
    begin
         if NodeItem = nil then NodeItem := Sender.items.getfirstnode
         else NodeItem := NodeItem.getfirstchild;
     
         if (NodeItem <> nil) and (NodeItem.text <> Name) then
         repeat
               NodeItem := NodeItem.getnextsibling;
         until (NodeItem = nil) or (NodeItem.text = Name);
         Result := NodeItem;
    end;
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Exemple de remplissage de treeview
    Par Tofalu dans le forum Contribuez
    Réponses: 15
    Dernier message: 21/01/2015, 17h15
  2. remplissage récursif d'un div
    Par rin01 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 05/01/2012, 19h10
  3. [Treeview] : Remplissage récursif
    Par freud dans le forum Composants VCL
    Réponses: 8
    Dernier message: 26/11/2009, 14h19
  4. 'erreur 35601' lors du remplissage treeview
    Par GAGNON dans le forum Access
    Réponses: 18
    Dernier message: 30/11/2006, 19h51
  5. [c#]Remplissage d'un treeview
    Par denden dans le forum Windows Forms
    Réponses: 3
    Dernier message: 29/06/2006, 14h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo