TStringgrid : Sortieren nach zwei Spalten

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
malabarista
Beiträge: 321
Registriert: Sa 11. Jun 2016, 12:16
OS, Lazarus, FPC: Linux Mint 18.1 L1.6.2-1 FPC 3.0.0
CPU-Target: 64Bit
Wohnort: Konstanz

TStringgrid : Sortieren nach zwei Spalten

Beitrag von malabarista »

Ist es möglich ein TStringgrid so einzustellen, dass er nach zwei Spalten sortiert.
Z.B. erst nach Spalte 1 sortieren und bei gleichen Einträgen in Spalte 1 dann nach Spalte 2 sortieren.

Beispiel

Code: Alles auswählen

 
Beilagen    Nudeln
Beilagen    Kartoffeln
Fisch       Zander
 

Im Beispiel sollte die 2.Zeile eigentlich als 1.Zeile stehen. Weil ich aber nur über die 1.Spalte sortieren kann, gibt es solche falschen Sortierungen.

Ich hoffe, mein Problem ist verständlich dargestellt.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: TStringgrid : Sortieren nach zwei Spalten

Beitrag von wp_xyz »

Ich nehme an, du musst dich in das OnCompareCells-Ereignis reinhängen, das die Spalten/Zeilen-Indices von zwei zu vergleichenden Zellen als Parameter hat: Wenn die erste Zelle "größer" ist als die zweite, also in der Sortierung "hinter" der zweiten kommen soll, muss der Eventhandler einen Wert > 0 zurückgeben, bei Gleichheit 0, und bei umgekehrter Reihenfolge einen Wert < 0.

OnCompareCells wird von der eingebauten Sort-Routine aufgerufen und hat als Spaltenindex der beiden Vergleichszellen immer den Index der zu sortierenden Spalte. In deinem Fall musst zu zusätzlich auch noch der Inhalt der alternativen Spalte suchen und zum Vergleich heranziehen, falls der Vergleich der primären Spalte den Funktionswert 0 ergibt. Und wenn die Eigenschaft SortOrder auf soDescending (abwärts) steht, dann drehst du einfach das Vorzeichen der Funktion um.

Etwa so, ungetestet:

Code: Alles auswählen

uses
  LazUTF8;
 
function TForm1.StringGrid1CompareCells((Acol, ARow, Bcol, BRow: Integer): Integer;
const
  SecCol = 1// Spaltenindex zu verwenden bei Gleichheit
var
  sa, sb: String;
begin
  sa := StringGrid1.Cells[ACol, ARow);
  sb := StringGrid1.Cells[BCol, BRow);
  Result := UTF8CompareText(sa, sb);
  if Result = 0 then begin
    sa := StringGrid1.Cells[SecCol, ARow];
    sb := StringGrid1.Cells[SecCol, BRow];
    Result := UTF8CompareText(sa, sb);
  end;
  if StringGrid1.SortOrder = soDescending then Result := -Result;
end;

malabarista
Beiträge: 321
Registriert: Sa 11. Jun 2016, 12:16
OS, Lazarus, FPC: Linux Mint 18.1 L1.6.2-1 FPC 3.0.0
CPU-Target: 64Bit
Wohnort: Konstanz

Re: TStringgrid : Sortieren nach zwei Spalten

Beitrag von malabarista »

ja, verstanden. ok. Danke

JimBob
Beiträge: 1
Registriert: Fr 20. Okt 2023, 11:57

Re: TStringgrid : Sortieren nach zwei Spalten

Beitrag von JimBob »

Dieses Snippet konnte ich (fast) ohne Änderung verwenden:
1. Eine CSV in StringGrid eingelesen.
2. Bei Änderung wird StringGrid.SortColRow aufgerufen.
3. Beim Event OnCompareCells das Snippet von wp_xyz rein.
4. SecCol im Snippet angepasst.

Getestet und es läuft so wie ich es brauchte.

Auf diesem Wege: Besten Dank an wp_xyz

Antworten