Stringgrid sortieren
-
- Beiträge: 67
- Registriert: So 17. Okt 2021, 17:18
- OS, Lazarus, FPC: Windows 7
- CPU-Target: X86
- Wohnort: Allgäu
Stringgrid sortieren
gibt es eine einfache Möglichkeit, die Reihen im Stringgrid nach dem Inhalt einer Spalte auf- bzw. absteigend zu sortieren? Komplizierte Lösungen sind mir schon eingefallen, wie z.B. das Exportieren des Inhalts in eine Excel-Datei, dort sortieren und dann wieder importieren.
Re: Stringgrid sortieren
Code: Alles auswählen
StringGrid1.SortColRow(true,1);
-
- Beiträge: 67
- Registriert: So 17. Okt 2021, 17:18
- OS, Lazarus, FPC: Windows 7
- CPU-Target: X86
- Wohnort: Allgäu
Re: Stringgrid sortieren
ok, vielen Dank. Dass es so einfach geht, hätte ich nicht gedacht. In Zukunft werde ich mir die Möglichkeiten genauer anschauen.
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Stringgrid sortieren
Hi!
Du kannst sogar numerisch sortieren.
1. StringGrid1.SortColRow(true,1);
So wird nach der ersten Spalte neben den "Fixed" sortiert.
2. Numerisch sortieren:
Dafür gibt es das event OnCompareCells. Dort hängt man diese Procedure ein:
Winni
Du kannst sogar numerisch sortieren.
1. StringGrid1.SortColRow(true,1);
So wird nach der ersten Spalte neben den "Fixed" sortiert.
2. Numerisch sortieren:
Dafür gibt es das event OnCompareCells. Dort hängt man diese Procedure ein:
Code: Alles auswählen
procedure TForm1.GridCompareCells(Sender: TObject; ACol, ARow, BCol, BRow: Integer; var Result: integer);
begin
result := StrToIntDef(Grid.Cells[ACol,ARow],0) -StrToIntDef (Grid.Cells[BCol,BRow],0);
if StringGrid1.SortOrder = soDescending then
result := -result;
end;
Winni
-
- Beiträge: 289
- Registriert: Mo 24. Aug 2020, 14:16
- OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
- CPU-Target: i386
Re: Stringgrid sortieren
...und dann kann man auch noch einfach ColumnClickSorts im ObjektInspektor auf True setzen...
-
- Beiträge: 67
- Registriert: So 17. Okt 2021, 17:18
- OS, Lazarus, FPC: Windows 7
- CPU-Target: X86
- Wohnort: Allgäu
Re: Stringgrid sortieren
es tut mir leid, wenn ich jetzt nochmal frage, aber bei mir wird die Spalte nicht richtig sortiert. Wenn ich die Sortierreihenfolge umkehre, steht die Spalte auf dem Kopf, aber genauso falsch sortiert wie vorher. In der Spalte stehen Werte, wie z.B. "107,45 USD", in der nächsten Zeile steht z.B. "508.386,25 USD" und dann "311,60 US". Die Lazarushilfe hat für mich keinen Wert, weil ich englisch nicht verstehe. Ich kann mir das nicht erklären. Die Reihen werden zwar anders angeordnet, aber nicht nach der Größe der Zahlen. ColumnClickSorts steht auf true und ob ich die Sortorder auf soDescending oder soAscending stelle, bewirkt nur eine Umkehr der falschen Reihenfolge. Was könnte ich wohl falsch machen?
Re: Stringgrid sortieren
Eigentlich hat dir Winni schon die Antwort gegeben.
Standardmässig wird nach Alphabet und nicht nach Zahlen sortiert.
Du musst also für deine gemischten Werte (Fliesskommazahl plus Text) deine eigene Vergleichsprozedur (was ist grösser/kleiner) basteln in OnCompareCells
Alphabetisch kommt halt immer "1" vor "2" und "3"
Also 1000 kommt vor 20 und 30000.
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Stringgrid sortieren
Hallo!
Also mal Grundsätzliches zur Arbeit mit Zahlen und Tabellen in Pascal:
* Der Dezimal-Separator ist der Punkt und nicht das deutsche Komma
* Tausender-Trenner sind nicht erlaubt, wenn man mit den Zahlen rechnen - also auch vergleichen - möchte.
* Buchstaben wie die Währungsangaben haben in dem Feld schon mal garnix zu suchen, sondern gehören in die nächste Spalte.
Aber um dich nicht völlig zu enttäuschen hab ich ne Routine geschrieben, die Deinen Verhau auf das richtige Fließkomma-Format bringt und dann die Zellen vergleicht.
Grüße
Winni
Also mal Grundsätzliches zur Arbeit mit Zahlen und Tabellen in Pascal:
* Der Dezimal-Separator ist der Punkt und nicht das deutsche Komma
* Tausender-Trenner sind nicht erlaubt, wenn man mit den Zahlen rechnen - also auch vergleichen - möchte.
* Buchstaben wie die Währungsangaben haben in dem Feld schon mal garnix zu suchen, sondern gehören in die nächste Spalte.
Aber um dich nicht völlig zu enttäuschen hab ich ne Routine geschrieben, die Deinen Verhau auf das richtige Fließkomma-Format bringt und dann die Zellen vergleicht.
Code: Alles auswählen
procedure TForm1.StringGrid1CompareCells(Sender: TObject; ACol, ARow, BCol,
BRow: Integer; var Result: integer);
function correctFloat (s : string): string;
var i : integer;
begin
result := '';
for i := 1 to length(s) do
if s[i] in ['0'..'9'] then result := result + s[i] else
if s[i]=',' then result := result +'.';
end; // correctFloat
begin
result := round(
StrToFloatDef(correctFloat(StringGrid1.Cells[ACol,ARow]),0) -
StrToFloatDef(correctFloat(StringGrid1.Cells[BCol,BRow]),0)
);
if StringGrid1.SortOrder = soDescending then
result := -result;
end;
Grüße
Winni
Re: Stringgrid sortieren
In den Zellen stehen Strings, die z.B. ein Datenbank-Export da reingeschrieben hat, und da ist alles erlaubt und möglich. Wenn der Programmierer damit rechnen will (z.B. sortieren), muss er sich die Zellen ansehen und gegebenenfalls so umformatieren, dass man damit rechnen kann. So wie du es in deinem Beispiel getan hast (das allerdings den Tausender-Trenner ignoriert).Winni hat geschrieben: Mi 19. Jan 2022, 18:02 * Der Dezimal-Separator ist der Punkt und nicht das deutsche Komma
* Tausender-Trenner sind nicht erlaubt, wenn man mit den Zahlen rechnen - also auch vergleichen - möchte.
* Buchstaben wie die Währungsangaben haben in dem Feld schon mal garnix zu suchen, sondern gehören in die nächste Spalte.
Aber zu fordern, dass in einem Zahlenstring ein Dezimalpunkt verwendet werden muss, kein Komma, und dass kein Tausendertrenner und kein Währungssymbol vorhanden sein darf, ist Unsinn.
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Stringgrid sortieren
Natürlich ignoriere ich die Tausender-Trenner. Sonst gibt es eine Exception in StrToFloatDef.wp_xyz hat geschrieben: Mi 19. Jan 2022, 20:03So wie du es in deinem Beispiel getan hast (das allerdings den Tausender-Trenner ignoriert).
Sehr hochqualifizierte Aussage: "Unsinn"Aber zu fordern, dass in einem Zahlenstring ein Dezimalpunkt verwendet werden muss, kein Komma, und dass kein Tausendertrenner und kein Währungssymbol vorhanden sein darf, ist Unsinn.
Winni
Re: Stringgrid sortieren
Sorry - da habe ich nicht so genau hingesehen... Aber das Minus-Zeichen ignorierst du. Ein Pluszeichen könnte auch drinnen stehen. Und wenn die Zahl in Exponentialdarstellung ist, fällt das 'E' oder 'e' unter den Tisch - obwohl das bei kaufmännischen Zahlen weniger das Problem sein sollte. Aber apropros kaufmännisch: die schreiben manchmal das Minuszeichen hinter die Zahl, oder setzen negative Zahlen in Klammern... Schließlich noch: StrToFloatDef braucht den in den Formatsettings festgelegten Dezimalseparator, das ist bei den meisten hier das Komma.
Trotzdem.
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Stringgrid sortieren
Hi!
Du trotziges Kind ....
Es gibt mehrere Versionen von StrToFloatDef. Mit und ohne FormatSettings. Die ohne nimmt den Punkt an.
Bei Minus gebe ich Dir recht. Plus darf man getrost ignorieren darf.
Wissenschaftliche Darstellung bei irgendwelchen Wechselkursen, Indizes oder Rechnungsbeträgen habe ich noch nie gesehen. Wer schreibt denn auch schon Rechnungen über 1E9 €. Außer Rüstungskonzernen .....
Winni
Du trotziges Kind ....
Es gibt mehrere Versionen von StrToFloatDef. Mit und ohne FormatSettings. Die ohne nimmt den Punkt an.
Bei Minus gebe ich Dir recht. Plus darf man getrost ignorieren darf.
Wissenschaftliche Darstellung bei irgendwelchen Wechselkursen, Indizes oder Rechnungsbeträgen habe ich noch nie gesehen. Wer schreibt denn auch schon Rechnungen über 1E9 €. Außer Rüstungskonzernen .....
Winni
Re: Stringgrid sortieren
Nur wenn deine Formatsettings den Punkt als Dezimaltrenner verwenden.Winni hat geschrieben: Mi 19. Jan 2022, 21:07 Es gibt mehrere Versionen von StrToFloatDef. Mit und ohne FormatSettings. Die ohne nimmt den Punkt an.
Code: Alles auswählen
program Project1;
uses
SysUtils;
var
s: String;
x: Double;
begin
WriteLn('DecimalSeparator: ', FormatSettings.DecimalSeparator);
s := '1,234';
x := StrToFloatDef(s, 0.0);
WriteLn('"', s, '" ---> x = ', x:0:3);
s := '1.234';
x := StrToFloatDef(s, 0.0);
WriteLn('"', s, '" ---> x = ', x:0:3);
ReadLn;
end.
Code: Alles auswählen
DecimalSeparator: ,
"1,234" ---> x = 1.234
"1.234" ---> x = 0.000
- af0815
- Lazarusforum e. V.
- Beiträge: 6770
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Stringgrid sortieren
Das die Tausendertrennzeichen nicht richtig ausgewertet werden, habe ich Erfahren, ist der Delphi-Kompatibilität geschuldet. Also meinen Lieblingssatz: Its not a bug, its per design.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Stringgrid sortieren
Hi!
Ich hab als System Suse Tumbleweed mit deutscher localisation.
Bei mir wird anstandslos bei StrToFloatDef ohne FormatSettings der Punkt angenommen.
Aber die Lokalisierung der Fortmatsettings ist einer der größten Mist-Bolzen, die Delphi je eingeführt hat. Ich erinnere mich noch gut: Hatte man das Zeugs auf dem einen Rechner am Laufen, versagte der gleiche Code auf dem nächsten Rechner. Das hat Unmengen von Stunden gekostet. U nd war voller Bugs.
Seitdem gehe ich dem Zeugs aus dem Weg und formatiere das in die gute alte Pascal-Schreibweise um. Und arbeite am Liebsten mit val.
Winni
PS.: Nachgeguckt:
function StrToFloatDef(const S: string; const Default: Extended): Extended;
ruft
StrToFloatDef(S,Default,DefaultFormatSettings);
und in denen steht:
DefaultFormatSettings : TFormatSettings = (
...
DecimalSeparator: '.';
...
Also geht das mit dem Punkt als DecimalSeparator höchst offiziell seinen korrekten Gang
Ich hab als System Suse Tumbleweed mit deutscher localisation.
Bei mir wird anstandslos bei StrToFloatDef ohne FormatSettings der Punkt angenommen.
Aber die Lokalisierung der Fortmatsettings ist einer der größten Mist-Bolzen, die Delphi je eingeführt hat. Ich erinnere mich noch gut: Hatte man das Zeugs auf dem einen Rechner am Laufen, versagte der gleiche Code auf dem nächsten Rechner. Das hat Unmengen von Stunden gekostet. U nd war voller Bugs.
Seitdem gehe ich dem Zeugs aus dem Weg und formatiere das in die gute alte Pascal-Schreibweise um. Und arbeite am Liebsten mit val.
Winni
PS.: Nachgeguckt:
function StrToFloatDef(const S: string; const Default: Extended): Extended;
ruft
StrToFloatDef(S,Default,DefaultFormatSettings);
und in denen steht:
DefaultFormatSettings : TFormatSettings = (
...
DecimalSeparator: '.';
...
Also geht das mit dem Punkt als DecimalSeparator höchst offiziell seinen korrekten Gang