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.