Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi TreeView aus DB mit parentIDs generieren (https://www.delphipraxis.net/107087-treeview-aus-db-mit-parentids-generieren.html)

rayj 22. Jan 2008 09:49

Datenbank: MSSQL • Version: 2000 • Zugriff über: ADO Components

TreeView aus DB mit parentIDs generieren
 
Guten Tag
Folgendes Problem:

------Tabelle categories--------
cat_id (pkey, aufzählend)
cat_pid (parent id, ID der übergeordneten Kategorie)
cat_name (varchar, Name/Beschreibung der Kategorie)
--------------------------------

Als Testdaten habe ich da jetzt mal:

id | name | pid |
1 IT 0
2 Software 1
3 Hardware 1
4 Delphi 2
5 C# 2
6 Verkauf 0

Soviel zur Datenbank. Daraus soll am Ende eine FAQ DB werden (Der Grund, warum ich es selber machen muss ist, dass später eigene Funktion eingebaut werden müssen).

Mein Problem: Wie bringe ich diese Struktur am saubersten (Hinsichtlich der Performance) in eine TreeView? :gruebel:

Habe jetzt ein DataSet mit allen Kategorien erstellt und nach pid sortiert.

Wie würdet ihr das machen, damit ich möglichst selten den commandtext des DS ändern muss, weil das ja relativ "lange" dauert und irgendwann alles verlangsamen würde.

Vielen Dank

rayj 22. Jan 2008 14:07

Re: TreeView aus DB mit parentIDs generieren
 
Vielleicht habe ich mich ein wenig unverständlich ausgedrückt.
Also ich habe jetzt testeshalber einfach mal einen (sehr schlechten) undynamischen Code der 2 Level der oben genannten Struktur in die TreeView schreibt.


Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  aNode, pNode: TTreeNode; //aktuellerNode, parentNode
begin
// TreeView aufbauen
TreeView1.Items.Clear;

dsCate.Close; //ado dataset
dsCate.CommandText := 'select * from cate where cat_pid = 0';
dsCate.Open;


while not dsCate.Eof do begin
  aNode := TreeView1.Items.AddChild(nil, dsCate.FieldByName('cat_name').AsString);

  query.Close;
  query.SQL.Clear;
  query.SQL.Add('select * from cate where cat_pid = ' + IntToStr(dsCate.FieldByName('cat_id').AsInteger));
  query.Open;

  if query.RecordCount > 0 then begin
      pNode := aNode;
      while not query.Eof do begin
        aNode := TreeView1.Items.AddChild(pNode, query.FieldByName('cat_name').AsString);
        query.Next;
      end;
  end;
  dsCate.Next;
end;
Allerdings soll das Programm am Ende beliebig viele "Parent-Level" besitzen und so kann ich das natürlich nicht hart-coden.

Versteht jemand mein Problem?

Jelly 22. Jan 2008 14:26

Re: TreeView aus DB mit parentIDs generieren
 
Du wirst um eine Rekursion nicht rumkommen.

Benutz mal die Suche hier im Forum. marabu hat mal hier eine Stored Procedure reingestellt, die dir die Daten bereits vom server her in der richtigen Reihenfolge liefert.

rayj 22. Jan 2008 14:36

Re: TreeView aus DB mit parentIDs generieren
 
Zitat:

Zitat von Jelly
Du wirst um eine Rekursion nicht rumkommen.

Benutz mal die Suche hier im Forum. marabu hat mal hier eine Stored Procedure reingestellt, die dir die Daten bereits vom server her in der richtigen Reihenfolge liefert.

Hi Jelly
Danke dir. Kannst Du dich evtl. noch an 1-2 Keywords erinnern die in seinem Thread vorkommen könnten?
Bei seinen >8k Posts ist es relativ schwierig, mit "stored procedure" von Author marabu konnte ich leider nichts dergleichen finden.

Grüsse

raiguen 22. Jan 2008 17:58

Re: TreeView aus DB mit parentIDs generieren
 
hier ein entsprechender Link

Jelly 23. Jan 2008 08:07

Re: TreeView aus DB mit parentIDs generieren
 
Wenn ich mir den Link so anschaue, war der Author doch nicht marabu... Da war wohl ein Pointer in meinem kopf verrutscht :wall:

alzaimar 23. Jan 2008 10:05

Re: TreeView aus DB mit parentIDs generieren
 
Ich habe es so gelöst (damit lassen sich auch Strukturen mit 100.000.000 Einträgen *sofort* in einer Treeview darstellen)

1. Treeview zeigt alle Root-Elemente. Jedes Root-Element enthält genau einen Kindknoten. Der ist als 'dummy' gekennzeichnet. Das Dummy-Kind ist nicht sichtbar (collapsed). dafür hat jeder Knoten ein '+', auch wenn er gar keine Kinder hat.
2. Im OnExpand-Ereignis prüfe ich, ob der Kindknoten ein Dummy ist. Wenn ja, wird er entfernt und die nächste Ebene aus der DB mittels 'Select * from TreeStructure where ParentID = <ID-des-expandierten-Knotens>' geladen und in die Treeview gepackt. Jeder Knoten erhält wieder einen 'dummy'-Childknoten.

Der Vorteil ist eben, das die Treeview unmittelbar zur Verfügung steht, egal wie groß die TreeStructure-Tabelle auf der DB-Seite ist. Ich habe damit alle Verwaltungsbezirk-Unterbezirk-Straßen-Hausnummern Berlins (ca. 2 Mio) dargestellt. Wer will schon in seiner Treeview ALLES sehen?

Vielleicht mach ich mal ein Demo-Projekt daraus und stelle es hier rein. Es scheint eine Standard-Anforderung zu sein.

Ansonsten sortierst Du die Knoten nach Parent-ID und fügst jeden Knoten an die entsprechende Stelle. Dabei suchst Du nicht *jedesmal* nach dem Parent-Node der Treeview, sondern nur dann, wenn sich die Parent-ID zwischen dem einzufügenden und dem vorherigen Eintrag geändert hat. Das geht auch recht flott.

Experimentier doch einfach mal damit und zeig uns Deine Ergebnisse. Es ist bestimmt interessant, ab wieviel Einträgen so ein statischen Laden aller Knoten zu langsam wird.

Ach ja, die TVirtualTreeView von Mike Lischke ist 1000x (mindestens) schneller als die Windows-Treeview und dürfte so bis zu einigen tausend statisch einzufügenden Knoten die richtige Wahl sein.

raiguen 23. Jan 2008 15:35

Re: TreeView aus DB mit parentIDs generieren
 
@ alzaimar: In der Art habe ich das für die Maschinen-/Bauteile-Struktur innerhalb meines InstandhaltungsProgrammes realisiert; allerdings habe ich den RootKnoten gezielt nur dann ein '+' zugeordnet, wenn auch definitiv weitere Kinder(=Ebenen) vorhanden sind. Hierzu habe ich intern ein entsprechendes Flag gesetzt, dh. sobald einem Knoten ein weiterer Kindknoten hinzugefügt wird, erhält der Elternknoten das entsprechende Flag (HasKids = true). Warum? Anwenderwunsch - weil: ein '+' zeigt halt eben an, dass weitere 'Unter'Struktur(en) vorhanden sind...
Im OnExpandEreignis wird die Anzahl der Kinder geprüft-> wenn 0 dann aus der DB nachladen... alles zusammen in Verbindung mit dem VirtualTree recht flott :thumb:

rayj 24. Jan 2008 19:45

Re: TreeView aus DB mit parentIDs generieren
 
Zitat:

Zitat von alzaimar
Ich habe es so gelöst (damit lassen sich auch Strukturen mit 100.000.000 Einträgen *sofort* in einer Treeview darstellen)

1. Treeview zeigt alle Root-Elemente. Jedes Root-Element enthält genau einen Kindknoten. Der ist als 'dummy' gekennzeichnet. Das Dummy-Kind ist nicht sichtbar (collapsed). dafür hat jeder Knoten ein '+', auch wenn er gar keine Kinder hat.
2. Im OnExpand-Ereignis prüfe ich, ob der Kindknoten ein Dummy ist. Wenn ja, wird er entfernt und die nächste Ebene aus der DB mittels 'Select * from TreeStructure where ParentID = <ID-des-expandierten-Knotens>' geladen und in die Treeview gepackt. Jeder Knoten erhält wieder einen 'dummy'-Childknoten.

Der Vorteil ist eben, das die Treeview unmittelbar zur Verfügung steht, egal wie groß die TreeStructure-Tabelle auf der DB-Seite ist. Ich habe damit alle Verwaltungsbezirk-Unterbezirk-Straßen-Hausnummern Berlins (ca. 2 Mio) dargestellt. Wer will schon in seiner Treeview ALLES sehen?

Vielleicht mach ich mal ein Demo-Projekt daraus und stelle es hier rein. Es scheint eine Standard-Anforderung zu sein.

Ansonsten sortierst Du die Knoten nach Parent-ID und fügst jeden Knoten an die entsprechende Stelle. Dabei suchst Du nicht *jedesmal* nach dem Parent-Node der Treeview, sondern nur dann, wenn sich die Parent-ID zwischen dem einzufügenden und dem vorherigen Eintrag geändert hat. Das geht auch recht flott.

Experimentier doch einfach mal damit und zeig uns Deine Ergebnisse. Es ist bestimmt interessant, ab wieviel Einträgen so ein statischen Laden aller Knoten zu langsam wird.

Ach ja, die TVirtualTreeView von Mike Lischke ist 1000x (mindestens) schneller als die Windows-Treeview und dürfte so bis zu einigen tausend statisch einzufügenden Knoten die richtige Wahl sein.

Grüss dich.
Also diese Idee finde ich wirklich klasse. Daran habe ich noch gar nicht gedacht.

Die VirtualTreeView habe ich auch schon gedownloaded, bisher allerdings noch nie benutzt weil sie ein bisschen komplizierter ist als die standard Delphi TV und mein Programm gleich um 400KB vergrösserte.

Ich weiss zwar noch nicht genau wieviele Einträge da maximal - jemals drin sein werden, vlt so 300-500.
Würdest du dafür schon die Virtual TreeView benutzen?

Danke auf jedenfall!

Alter Mann 24. Jan 2008 20:20

Re: TreeView aus DB mit parentIDs generieren
 
Hi,

warum benutzt du nicht DB-TreeView, es verlangt genau diese Art von Struktur.

Gruß


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:46 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz