Einzelnen Beitrag anzeigen

ByTheTime

Registriert seit: 24. Sep 2011
Ort: Frankfurt
297 Beiträge
 
Delphi XE2 Architect
 
#1

Firemonkey Treeview mit Daten aus ClientDataSet füllen

  Alt 22. Okt 2014, 21:41
Moinsen
Ich stehe vor einem kleinen Problem. Ich glaube es ist garnicht mal so schwer zu lösen aber irgendwie habe ich eine Denkblokade... Ich komme einfach nicht weiter

Ich habe am Rand meiner Firemonkey/FireUI Test App eine TTreeView Komponente. Diese möchte ich nun zur Laufzeit mit Daten aus einem TClientDataSet füllen. Allerdings bekomme ich das nicht ganz hin.

Bevor etwas Code kommt, noch ein bisschen Theorie. Ein Datensatz im DataSet sieht so aus: "Jahr; KW*; Tag; ID; { ... }". *KW = Kalenderwoche. Jetzt möchte ich eine Hierarchie ausgehend von diesen Feldern erstellen. Nehmen wir an der erste Datensatz sieht so aus: "2014; 43; 2; 1;" (Der Tag wird ebenfalls als Zahl gespeichert, also 2 = Dienstag). Dementsprechend soll mein Treeview dann so aussehen:

"2014"
-> "37"
-> "2"
-> "1"
Wenn die nächsten beiden Datensätze nun so aussehen: "2014; 43; 2; 2;" und "2014; 43; 2; 3;" (Gleiches Jahr/KW/Tag), sollen diese dem TreeView an entsprechender Stelle angefügt werden. Da Jahr, Kalenderwoche und der Tag im TreeView schon existieren, werden die beiden ID's also die Childs von "2" (Dienstag):

"2014"
-> "37"
-> "2"
-> "1"
-> "2"
-> "3"
Genauso verhält sich das auch mit den anderen Feldern. Wenn der Tag/KW/Jahr noch nicht im TreeView existiert, wird er eingefügt, so das sich eine Struktur wie diese ergibt:


"2014"
-> "37"
-> "2"
-> "1"
-> "2"
-> "3"
"2015"
-> "1"
-> "1"
-> "1"
-> "2"
-> "1"
-> "2"
{ ... }

Ich hoffer man versteht meine super-dolle Erklärung

So... Nach professioneller Erklärung und Schemazeichnung folgt jetzt Amateurhafter Schüler-Code

Delphi-Quellcode:
procedure TfrmMain.CreateTree;
var
  TreeItems: array of TTreeViewItem;
  LetztesJahr, LetzteKW, LetzterTag: TTreeViewItem;

  function ItemExists(AText: String): Boolean;
  var
    I: Integer;
  begin
    Result := False;

    if Length(TreeItems) > 0 then
      for I := Low(TreeItems) to High(TreeItems) do
        if TreeItems[I].Text = AText then
        begin
          Result := True;
          Break;
        end;
  end;

begin
  ClientDataSet1.First;

  while not ClientDataSet1.Eof do
  begin

    // Jahr

    if not ItemExists(ClientDataSet1.Fields[0].AsString) then
    // Wenn der Text noch nicht im TreeView ist (nich keinem Item zugewießen)...
    begin
      SetLength(TreeItems, Length(TreeItems) + 1); // Item-Array erweitern
      TreeItems[High(TreeItems)] := TTreeViewItem.Create(Self); // Item erzeugen
      TreeItems[High(TreeItems)].Text := ClientDataSet1.Fields[0].AsString;
      // Item Text := Wert aus Feld
      TreeItems[High(TreeItems)].Parent := TreeView1; // Parent := TreeView1
      TreeItems[High(TreeItems)].Expand; // Ausklappen

      LetztesJahr := TreeItems[High(TreeItems)]; // siehe bei KW
    end;


    // KW

    if not ItemExists(ClientDataSet1.Fields[1].AsString) then
    // Wenn der Text noch nicht im TreeView ist (nich keinem Item zugewießen)...
    begin
      SetLength(TreeItems, Length(TreeItems) + 1); // Item-Array erweitern
      TreeItems[High(TreeItems)] := TTreeViewItem.Create(Self); // Item erzeugen
      TreeItems[High(TreeItems)].Text := ClientDataSet1.Fields[1].AsString;
      // Item Text := Wert aus Feld
      TreeItems[High(TreeItems)].Parent := LetztesJahr;
      // Parent := Letztes Jahr
      TreeItems[High(TreeItems)].Expand; // Ausklappen

      LetzteKW := TreeItems[High(TreeItems)]; // siehe bei Tag
    end;


    // Tag

    if not ItemExists(ClientDataSet1.Fields[2].AsString) then
    // Wenn der Text noch nicht im TreeView ist (nich keinem Item zugewießen)...
    begin
      SetLength(TreeItems, Length(TreeItems) + 1); // Item-Array erweitern
      TreeItems[High(TreeItems)] := TTreeViewItem.Create(Self); // Item erzeugen
      TreeItems[High(TreeItems)].Text := ClientDataSet1.Fields[2].AsString;
      // Item Text := Wert aus Feld
      TreeItems[High(TreeItems)].Parent := LetzteKW;
      // Parent := Letzte Kalenderwoche
      TreeItems[High(TreeItems)].Expand; // Ausklappen

      LetzterTag := TreeItems[High(TreeItems)]; // siehe bei ID
    end;


    // ID

    if not ItemExists(ClientDataSet1.Fields[3].AsString) then
    // Wenn der Text noch nicht im TreeView ist (nich keinem Item zugewießen)...
    begin
      SetLength(TreeItems, Length(TreeItems) + 1); // Item-Array erweitern
      TreeItems[High(TreeItems)] := TTreeViewItem.Create(Self); // Item erzeugen
      TreeItems[High(TreeItems)].Text := ClientDataSet1.Fields[3].AsString;
      // Item Text := Wert aus Feld
      TreeItems[High(TreeItems)].Parent := LetzterTag; // Parent := Letzter Tag
      TreeItems[High(TreeItems)].Expand; // Ausklappen
    end;

    ClientDataSet1.Next;
    // Weiter und wieder von vorne für nächsten Datensatz...
  end;

  { if Length(TreeItems) = 0 then
    TreeView1.ExpandAll; }

end;
Ich habe im Anhang nochmal ein Demo-Programm zusammengenagelt inklusive Quellen. Es ist mit der XE7 Trial erstellt worden, deshalb weiß ich nicht wie es mit der Abwärtskompatibilität aussieht Wenn abwärtskompatibel, dann wohl ab XE2, da LiveBindings.

Auf jeden Fall haut mein Code nicht hin, und ich kreige einfach nich raus woran es liegt. Im Kopf habe ich mir das alles einfach zurechtgelegt, aber natürlich funktioniert es nie so wie man will.

Ich hoffe ihr könnt mir helfen, denn ich zerbreche mir hier schon den ganzen Abend den Kopf.

Gruß

* Ein Fehler ist mir schonmal ins Netz gegangen: Die if-Abfrage haut nicht hin, den die Funktion ItemExists gibt ja schon True zurück, wenn nur ein Item mit dem selben Text existert. Das heißt wenn ich einmal das Feld ID mit dem Wert 1 hinzugefügt habe, geht das dannach nicht mehr. Obwohl es ja mehrmals vorkommen kann/soll.

** Anhang vergessen, ist jetzt dabei.
Angehängte Dateien
Dateityp: zip TreeView Test.zip (3,21 MB, 3x aufgerufen)
Lukas

Geändert von ByTheTime (22. Okt 2014 um 22:14 Uhr) Grund: Anhang vergessen
  Mit Zitat antworten Zitat