Hi Onkelrossie,
da ich bald ein ähnliches Problem vor mir hab (es rückt auf meiner ToDo-List immer weiter nach unten
), hab ich mich mal dran gemacht:
(Ich hab einfach mal deine Prozedur erweitert)
Delphi-Quellcode:
procedure TForm1.LVtoVST;
function StrCompare(s1, s2: String): Integer;
// Liefert die Anzahl der maximal übereinstimmenden Zeichen (vom Anfang).
var
i, min: Integer;
begin
min := Length(s1);
if (Length(s2) < min) then
min := Length(s2);
result := 0;
for i := min downto 1 do
if (Copy(s1, 1, i) = Copy(s2, 1, i)) then
begin
result := i;
break;
end;
end;
function FindRootNode(Caption, SubItem: String; var c0, c1: Integer): PVirtualNode;
// Prüft, ob es schon eine Kategorie gibt, in die der Artikel rein passt.
// c0 und c1 enthalten die Anzahl der Zeichen, die alle Untereinträge gemeinsam haben.
var
Node: PVirtualNode;
Data: PTreeData;
c: Integer;
begin
c0 := 0;
result := nil;
Node := VST.GetFirst;
while Assigned(Node) do
begin
Data := VST.GetNodeData(Node);
c := StrCompare(Caption, Data.FColumn0);
if (c > c0) then
begin
c0 := c;
c1 := StrCompare(SubItem, Data.FColumn1);
result := Node;
end;
Node := VST.GetNextSibling(Node);
end;
end;
var
I, c0, c1: Integer;
TreeData: TTreeData;
RootNode: PVirtualNode;
Data: PTreeData;
begin
CreateCols; //cols erstellen
VST.NodeDataSize:= SizeOf(TTreeData); //größe zuweisen
VST.BeginUpdate;
for I := 0 to ListView1.Items.Count - 1 do //ListView durchlaufen, auslesen
begin
with TreeData do
begin //und in den Record speichern
FColumn0:= ListView1.Items[i].Caption;
FColumn1:= ListView1.Items.Item[i].SubItems[0];
FColumn2:= ListView1.Items.Item[i].SubItems[1];
FColumn3:= ListView1.Items.Item[i].SubItems[2];
RootNode := FindRootNode(FColumn0, FColumn1, c0, c1);
end;
if (RootNode = nil) then
begin
RootNode := AddVSTStructure(VST, nil, TreeData); // Kategorie erstellen
AddVSTStructure(VST, RootNode, TreeData); // Artikel eintragen
end
else
begin
AddVSTStructure(VST, RootNode, TreeData); // Artikel eintrage
Data := VST.GetNodeData(RootNode); // Überschriften anpassen
Data.FColumn0 := Copy(Data.FColumn0, 1, c0);
Data.FColumn1 := Copy(Data.FColumn1, 1, c1);
end;
end;
VST.EndUpdate;
end;
Die Idee ist recht einfach: Vor dem eintragen, wird erst geprüft, ob es eine Kategorie gibt, in die der Artikel passt.
Falls nicht, wird erst eine erstellt, die genauso heißt.
Falls ja, werden die ersten beiden Überschriften (ist natürlich auch auf alle vier erweiterbar) so gekürzt, dass sie für alle Untereinträge passen.
lg NicNacMan