0 users online | 0 Guests and 0 Registered

»

ID #1000

Einen TreeView dynamisch mit Daten aus einer Datenbank füllen

In diesem Beispiel wird gezeigt, wie aus dem Inhalt zweier Tabellen ein Baum in der Komponente TTreeView erstellt wird. Dabei kann der Baum mehrere Unterebenen haben.

Beispieltabellen für das Codebeispiel: (in beiden Tabellen ist das Feld ID auf AutoInc) :

CREATE TABLE CATEGORY (
    ID           INTEGER NOT NULL,
    PARENTID     INTEGER,
    DESCRIPTION  VARCHAR(50) NOT NULL,
    "SEQUENCE"   INTEGER NOT NULL
);

CREATE TABLE Sourcecode (
    ID           INTEGER NOT NULL,
    CATID        INTEGER NOT NULL,
    HEADER       VARCHAR(255) NOT NULL,
    CODE         BLOB SUB_TYPE 0 SEGMENT SIZE 120 NOT NULL,
    DESCRIPTION  BLOB SUB_TYPE 0 SEGMENT SIZE 120 NOT NULL,
    NOTES        BLOB SUB_TYPE 0 SEGMENT SIZE 120 NOT NULL
);


Hier nun die Procedure, die den TreeView mit den Daten füllt :

procedure TForm3.FillTreeView;

  function GetDescription(id: integer):string;
  begin
    with IBQuery1 do
    begin
      SQL.Clear;
      SQL.Text := 'SELECT description FROM category where id=' + IntToStr(id);
      Open;
      result := Fields[0].AsString;
      Close;
    end;
  end;

  function GetParentID(id: integer):integer;
  begin
    with IBQuery1 do
    begin
      SQL.Clear;
      SQL.Text := 'SELECT parentid from category where id=' + IntToStr(id);
      Open;
      result := Fields[0].AsInteger;
      Close;
    end;
  end;

  function TreeItemSearch(TV: TTreeView; SearchItem: string; ParentItem: integer): TTreeNode;
  var
    i : Integer;
  begin
    result := nil;
    if (TV = nil) or (SearchItem = '') then Exit;
    for i := 0 to TV.Items.Count - 1 do
    begin
      if SearchItem = TV.Items.Item[i].Text then
      begin
        if TV.Items.Item[i].Parent.Index = -1 then
        begin
          result := TV.Items.Item[i];
          Exit;
        end
        else
          if TV.Items.Item[i].Parent.Text = GetDescription(ParentItem) then
          begin
            result := TV.Items.Item[i];
            Exit;
          end;
      end;
    end;
  end;

  function TreeNodeSearch(aNode: TTreeNode; SearchItem: string): TTreeNode;
  var
    I: Integer;
  begin
    result := nil;
    if (aNode = nil) or (SearchItem = '') then Exit;
    for I := 0 to aNode.Count - 1 do
    begin
      if SearchItem = aNode.Item[i].Text then
      begin
        Result := aNode.Item[i];
        exit;
      end;
    end;
  end;
var
  tmpNode: TTreeNode;
  pid: Integer;

begin
  with IBQuery2 do
  begin
    SQL.Clear;
    SQL.Text := 'SELECT c.*, f.* FROM Category c LEFT JOIN FAQ f ON f.CatId = c.ID ORDER BY c.PARENTID ASC, c.DESCRIPTION, f.HEADER;';
    Open;
    while not eof do
    begin
      pid := GetParentID(FieldByName('ParentId').AsInteger);
      if TreeNodeSearch(TreeItemSearch(TreeView1, GetDescription(FieldByName('ParentID').AsInteger), pid), FieldByName('Description').AsString) = nil then
      begin
        tmpNode := TreeView1.Items.AddChild(TreeItemSearch(TreeView1, GetDescription(FieldByName('ParentID').AsInteger), pid), FieldByName('Description').AsString);
      end;
      if (TreeItemSearch(TV_Category, GetDescription(FieldByName('ParentID').AsInteger), pid) <> nil) and (FieldByName('Header').AsString <> '') then
        TreeView1.Items.AddChild(tmpNode, FieldByName('Header').AsString);
      next;
    end;
  end;
end;

Eine kurze Erklärung :
Die SELECT-Abfrage wird ausgeführt, danach geht die While-Schleife jeden Datensatz durch. Dabei wird überprüft, ob die aktuelle Category schon erstellt ist. Ist dieses nicht der Fall, wird nach der FirstNode gesucht und die TreeNode oder nil zurückgegeben. Wird nil zurückgegeben, dann wird die neue Node erstellt und zwischengespeichert. In der zweiten IF-Abfrage wird dann zur Node noch die Überschrift als NodeChild eingefügt.
Damit erhalte ich den kompletten Kategorienbaum mit mehreren Nodes und in der letzten Node noch die Überschrift des Eintrags für die Kategorie.

Tags: -

Related entries: -

Last update: 2009-10-14 11:13
Author: Rolf Warnecke
Revision: 1.3

{writePrintMsgTag} {writeSend2FriendMsgTag} {writePDFTag}
Please rate this FAQ:

Average rating: 3.33 (3 Votes)

completely useless 1 2 3 4 5 most valuable

You can comment this FAQ

Most popular FAQs RSS

  1. Display Resolution change
    (30 views)
  2. Scanned a Picture
    (13 views)

Latest FAQs RSS

  1. Scanned a Picture
    (2010-11-19 06:01)
  2. Display Resolution change
    (2010-02-09 18:01)