Wybieranie danych rekurencyjnie z bazy i tworzenie TTreeView

Wybieranie danych rekurencyjnie z bazy i tworzenie TTreeView
BU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 297
0

Witam forumowiczów,
Odwieczny temat rzeka, czyli rekurencja. Czy jakaś dobra duszyczka pomoże ogarnąć i podpowie, jak dobrze napisać funkcję w rekurencji? Mam tabelę, elementów, które zawierają id swojego rodzica. Chcę je umieścić w komponencie TTreeView. Zacząłem budować funkcję, ale się zaciąłem i nie wiem jak pociągnąć. Podpowie ktoś?
Moja funkcja:

Kopiuj
function TForm1.getTree(parentId: Integer = 0; destNode: string = ''): string;
var
  i: integer;
  dNode: TTreeNode;
begin
  db.dbQuery.Active := False;
  db.dbQuery.SQL.Text := 'SELECT * FROM EDI_TplElements WHERE element_parent_id = ' + IntToStr(parentId);
  db.dbQuery.Active := True;
  for i := 0 to db.dbQuery.RecordCount - 1 do
  begin
    dNode := FindRootNode(destNode, TreeView1);
    if dNode <> nil then
    begin
      TreeView1.Items.Add(dNode, db.dbQuery.FieldByName('element_name').AsString);
    end else
    begin
      TreeView1.Items.Add(nil, db.dbQuery.FieldByName('element_name').AsString);
    end;

  end;

end;

A funkcja FindRootNode wygląda tak:

Kopiuj
function FindRootNode(ACaption: String; ATreeView: TTreeView): TTreeNode;
var LCount: Integer;
begin
  result := nil;
  LCount := 0;
  while (LCount < ATreeView.Items.Count) and (result = nil) do
  begin
    if (ATreeView.Items.Item[LCount].Text = ACaption) and (ATreeView.Items.Item[LCount].Parent = nil) then
      result := ATreeView.Items.Item[LCount];
    inc(LCount);
  end;
end;
GS
  • Rejestracja: dni
  • Ostatnio: dni
3

Przechwytywanie1.JPGPrzechwytywanie2.JPGtreeTest.zip

Kopiuj
unit Unit4;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, generics.Collections, Vcl.ComCtrls, Data.DBXFirebird, Data.DB, Data.SqlExpr, Vcl.StdCtrls;

Type
  TelementsList = class;

  Telement = class
    id: int64;
    parentId: int64;
    elementValue: string;
    childNodes: TelementsList;
    constructor Create;
    destructor Destroy;
  end;

  TelementsList = class(TobjectList<Telement>)
    procedure prepareTree;
  end;

type
  TForm4 = class(TForm)
    TreeView1: TTreeView;
    FbconnectionConnection: TSQLConnection;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    procedure addToTree(aElement: Telement; aParentNode: TTreenode);
    { Private declarations }
  public
    { Public declarations }
    elementsList: TelementsList;
    procedure loadFromdb;
    procedure createTreeView;
  end;

var
  Form4: TForm4;

implementation

{$R *.dfm}
{ TelementsList }

procedure TelementsList.prepareTree;
var
  I, j: Integer;
begin
  for I := 0 to self.Count - 1 do
    for j := 0 to self.Count - 1 do
      if self[I] <> self[j] then
        if self[j].parentId = self[I].id then
          self[I].childNodes.Add(self[j]);
end;

{ Telement }

constructor Telement.Create;
begin
  self.childNodes := TelementsList.Create(false);
end;

destructor Telement.Destroy;
begin
  self.childNodes.Free;

end;

{ TForm4 }

procedure TForm4.Button1Click(Sender: TObject);
begin
  self.loadFromdb;
end;

procedure TForm4.createTreeView;
var
  I: Integer;
begin
  for I := 0 to self.elementsList.Count - 1 do
    if (self.elementsList[I].parentId = 0) then
      addToTree(self.elementsList[I], nil);

end;

procedure TForm4.FormCreate(Sender: TObject);
begin
  self.elementsList := TelementsList.Create(true);
end;

procedure TForm4.FormDestroy(Sender: TObject);
begin
  self.elementsList.Free;
end;

procedure TForm4.loadFromdb;
var
  tsql: tsqldataset;
  newElement: Telement;
begin
  self.elementsList.Clear;
  self.TreeView1.Items.Clear;
  tsql := tsqldataset.Create(nil);
  try
    tsql.SQLConnection := self.FbconnectionConnection;
    tsql.CommandText := 'select id,parent_id,element_value from new_table';
    tsql.Open;
    while not tsql.eof do
    begin
      newElement := Telement.Create;
      newElement.id := tsql.FieldByName('id').AsLargeInt;
      newElement.parentId := tsql.FieldByName('parent_id').AsLargeInt;
      newElement.elementValue := tsql.FieldByName('element_value').AsString;
      self.elementsList.Add(newElement);
      tsql.Next;
    end;
  finally
    tsql.Free;
  end;
  self.elementsList.prepareTree;
  self.createTreeView;
end;

procedure TForm4.addToTree(aElement: Telement; aParentNode: TTreenode);
var
  I: Integer;
  newElement: TTreenode;
begin
  newElement := self.TreeView1.Items.AddChild(aParentNode, aElement.elementValue);
  for I := 0 to aElement.childNodes.Count - 1 do
    addToTree(aElement.childNodes[I], newElement);

end;

end.
GS
  • Rejestracja: dni
  • Ostatnio: dni
0

Spakowany projekt :
treeTest.zip

BU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 297
0

Dzięęęęęęęki!!!!! Działa!!!!!

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.