Patrix2911 hat geschrieben:derem Verständnis ich scheinbar nicht würdig bin.  
  
Dann wird's Zeit, dem Verständinis auf die Sprünge zu helfen.
In deinem konkreten Fall würde ich das Memo Zeile für Zeile durchlaufen und  jeden String in die einzelnen Wörter aufspalten, wobei die letzten beiden später wieder zusammengefasst werden müssen:
Code: Alles auswählen
var
  arr: TStringArray;
...
  arr := Memo1.Lines[index].Split;
Bei der fest vorgegebenen Struktur des Baums brauchst du dann 4 Variablen für Nodes: node1 für SOLs, node2 für 11380, node3 für l, m etc, node4 für "royal blue" etc.
Beim Durchlaufen der Strings erzeugst du den 1.Node mit dem Element arr[0] und Parent nil:
Die "11380" ist ein Kind von "SOLs", analog ist "l" ein Kind von "11380", usw. Also
Code: Alles auswählen
  node2 := TreeView1.Items.AddChild(node1, arr[1]);
  node3 := TreeView1.Items.AddChild(node2, arr[2]);
  node4 := TreeView1.Items.Addchild(node3, arr[3] + ' ' + arr[4]);
Das stimmt aber nicht ganz, weil nun für jede Memo-Zeile ein "SOLs" Node erzeugt wird. Daher musst du, bevor du die neuen Nodes erzeugst, suchen, ob es diese vielleicht schon gibt. Dazu prüft die folgende Funktion einen Node, ob sein "Text" dem Suchtext entspricht, also "SOLs" oder "11380" oder "m" oder "l" usw. Wenn das so ist, dann wird die Funktion verlassen, und der Node als Funktionswert übergeben. Wenn nicht, wird die Funktion mit dem ersten Kindknoten und den nächsten Geschwisterknoten aufgerufen. Dadurch wird effektiv der gesamte bereits angelegte Baum durchforstet. Erst wenn ganz am Ende nichts gefunden worden ist, wird das Funktionsergebnis nil.
Code: Alles auswählen
// Suche den Node im gesamten Tree, der den angegebenen Text als Caption hat
function TForm1.FindNode(ACaption: String; ANode: TTreeNode): TTreeNode;
var
  sibling, child: TTreeNode;
begin
  if ANode = nil then begin
    if TreeView1.Items.Count = 0 then begin
      Result := nil;
      exit;
    end else
      ANode := TreeView1.Items[0];
  end;
 
  // Prüfe den Node selbst
  if ANode.Text = ACaption then begin
    Result := ANode;
    exit;
  end;
 
  // Prüfe alle "Kinder" von ANode
  child := ANode.GetFirstChild;
  if child <> nil then begin
    Result := FindNode(ACaption, child);  // child prüft seine eigenen Kinder und Geschwister und immer so weiter
    if Result <> nil then exit;
  end;
 
  // Prüfe Geschwister
  sibling := ANode.GetNextSibling;
  if sibling <> nil then begin
    Result := FindNode(ACaption, sibling);  // sibling prüft seine eigenen Kinder und die folgenden Geschwister
    if Result <> nil then
      exit;
  end; 
 
  // Nichts gefunden
  Result := nil;
end;
Um die bereits existierenden Nodes zu berücksichtigen, musst du also "FindNode" aufrufen. Das Ergebnis nimmst du als Parent für den nächsten Teilstring des Memos, bzw. falls der Node nicht gefunden wurde, musst du ihn wie oben erläutert neu erzeugen:
Code: Alles auswählen
procedure TForm1.MemoToTree;
var
  i: Integer;
  arr: TStringArray;
  node1, node2, node3, node4: TTreeNode;
begin
  for i:=0 to Memo1.Lines.Count-1 do begin
    arr := String(Memo1.Lines[i]).Split(' ');
 
    node1 := FindNode(arr[0], nil);
    if node1 = nil then
      node1 := TreeView1.Items.AddChild(nil, arr[0]);
 
    node2 := FindNode(arr[1], node1);
    if node2 = nil then
      node2 := TreeView1.items.AddChild(node1, arr[1]);
 
    node3 := FindNode(arr[2], node2);
    if node3 = nil then
      node3 := TreeView1.Items.AddChild(node2, arr[2]);
 
    node4 := FindNode(arr[3] + ' ' + arr[4], node3);
    if node4 = nil then
      node4 := TreeView1.Items.AddChild(node3, arr[3] + ' ' + arr[4]);
  end;
  TreeView1.FullExpand;
end;
Es gibt sicher noch andere Herangehensmöglichkeiten. Zwangsläufig wirst du immer auf eine rekursive Funktion, also eine Funktion, die sich immer wieder mit geänderten Parametern selbst aufruft. Bei rekursiven Funktionen habe ich immer das Gefühl, jemand würde mein Gehirn umdrehen... Aber diese Dinger sind sehr elegant und gerade bei Bäumen unerlässlich.