Einzelnen Beitrag anzeigen

Delphi.Narium

Registriert seit: 27. Nov 2017
2.431 Beiträge
 
Delphi 7 Professional
 
#4

AW: Alphanumerische Stringsortierung

  Alt 16. Jul 2019, 08:57
Kennt VST (analog zu TStringList) eine Methode CustomSort?

Eventuell geht auch das Ereignis TVTCompareEvent = procedure(Sender: TBaseVirtualTree; Node1, Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer) of object; In der Ereignisroutine kannst Du dann Vergleiche nach "Deinem Gutdünken" beeinflussen.
Nur als hingedaddelte Idee (ohne irgendeine Garantie für irgendwas )
Delphi-Quellcode:
procedure TForm1.OnTVTCompare(Sender: TBaseVirtualTree; Node1, Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer);
Var
  Data1 : String;
  Data2 : String;
  IsNumber1 : Boolean;
  IsNumber2 : Boolean;
  l1 : Integer;
  l2 : Integer;
  i : Integer;
begin
  Data1 := Node1.Data; // Muss sicherlich irgendwie angepasst werden.
  Data2 := Node2.Data; // dito.
  // Rückgabewert = 0: Node1 und Node2 sind gleich
  // Rückgabewert < 0: Node1 ist kleiner als Node2
  // Rückgabewert > 0: Node2 ist größer als Node1
  Result := 0; // Wie gehen einfach erstmal von Gleichheit aus.
  // Zuerst auf Gleichheit prüfen.
  // Ist sie gegeben, können wir die Routine verlassen, der Rückgabewert ist mit 0 ok.
  if Data1 = Data2 then exit
  else begin
    l1 := Length(Data1);
    l2 := Length(Data2);
    for i := Min(l1,l2) do begin
      // Feststellen, ob beide nummerisch sind:
      // Normalerweise sind nummerische Werte < als Zeichen.
      IsNumber1 := Data1[i] < 'A';
      IsNumber2 := Data2[i] < 'A';
      // Zahl 1 ist größer als Buchstabe 2
      If IsNumber1 and not IsNumber2 then Result := 1 else
      // Zahl 2 ist größer als Buchstabe 1
      If IsNumber2 and not IsNumber1 then Result := -1 else
      // Zeichen ohne Beachtung von Groß-/Kleinschreiung vergleichen.
      // Der Rückgabewert von AnsiCompareText ist kompatibel zu dieser Routine.
      Result := AnsiCompareText(Data1[i],Data2[i]);
      // Ist Result nicht mehr = 0, so wurde ein Unterschied festgestellt
      // und wir können die Schleife verlassen.
      if Result <> 0 then break;
    end;
    // Ist hier Result = 0 dann ergibt sich das Ergebnis aus dem Längenunterschied:
    if Result = 0 then Result := l1 - l2;
  end;
end;
Was ich nicht weiß ist, ob die Sortierung auch bei sowas noch annähernd richtig wird:
Code:
AbcdeA
Abcdeb
Abcdeba
Abcdeba1
Abcdeba2
Abcde1
Abcde2
BCDeF0A
BCDeF0B
BCDeF01
01345aB
01345AC
01345a1
Und mir ist klar, dass .Data im realen Leben nicht wirklich miteinander verglichen werden können, Du musst hier also eine für Deine Daten passende "Alternative" einbauen
  Mit Zitat antworten Zitat