Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Stringgrid sortieren (https://www.delphipraxis.net/119560-stringgrid-sortieren.html)

bl3nder 28. Aug 2008 10:10


Stringgrid sortieren
 
Hallo,

Zu diesem Thema gibt es schon einige Einträge in diesem Forum.

Es wurde auf diese Seite verwießen:
http://www.torry.net/pages.php?id=114

Und dieser Vorschlag gemacht:

Delphi-Quellcode:
procedure TForm1.SortStringGrid(var GenStrGrid: TStringGrid; ThatCol: Integer);
const
  // Define the Separator
  TheSeparator = '@';
var
  CountItem, I, J, K, ThePosition: integer;
  MyList: TStringList;
  MyString, TempString: string;
begin
  // Give the number of rows in the StringGrid
  CountItem := GenStrGrid.RowCount;
  //Create the List
  MyList       := TStringList.Create;
  MyList.Sorted := False;
  try
    begin
      for I := 1 to (CountItem - 1) do
        MyList.Add(GenStrGrid.Rows[I].Strings[ThatCol] + TheSeparator +
          GenStrGrid.Rows[I].Text);
      //Sort the List
      Mylist.Sort;

      for K := 1 to Mylist.Count do
      begin
        //Take the String of the line (K – 1)
        MyString := MyList.Strings[(K - 1)];
        //Find the position of the Separator in the String
        ThePosition := Pos(TheSeparator, MyString);
        TempString := '';

        {Eliminate the Text of the column on which we have sorted the StringGrid}











        TempString := Copy(MyString, (ThePosition + 1), Length(MyString)); // [Pascal Fehler] Search.pas(748): E2066 Operator oder Semikolon fehlt
















        MyList.Strings[(K - 1)] := '';
        MyList.Strings[(K - 1)] := TempString;
      end;

      // Refill the StringGrid
      for J := 1 to (CountItem - 1) do
        GenStrGrid.Rows[J].Text := MyList.Strings[(J - 1)];
    end;
  finally
    //Free the List
    MyList.Free;
  end;
end;


procedure TForm1.GridMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
Var
  i,breite,spalte:Integer;
begin
if y<=Grid.RowHeights[0] then
begin
  breite:=0;
  For i:=0 To Grid.ColCount-1 Do
  Begin
    breite:=breite+Grid.ColWidths[i];
    if breite>x Then
    Begin
      spalte:=i;
      Break;
    end;
  end;
  SortStringGrid(Grid, spalte);
end;
end;
Leider bekomme ich bei dem "geklauten" Code eine Fehlermeldung.
Weiß einer was an der Zeile falsch ist ? Find in der Hilfe auch nichts zu der Copy Methode (TMenuitem ?? :/)

Edit:
Im Handbuch findet man unter TMenuItem keine Methode namens "Copy".
Wenn ich aber im Code mit der Maus über "Copy(MyString, (ThePosition + 1), Length(MyString));" fahre, dann wird als Quickinfo folgendes gezeigt:
copy - Menus.TMenuItem

?

taaktaak 28. Aug 2008 10:45

Re: Stringgrid sortieren
 
Moin, Moin.
Mit TMenuItem hat das sicherlich nix zu tun!
Hast du den grundsätzliche Ablauf verstanden?

Du kopierst alle Zeilen des Grids in eine Liste, sortierst diese und füllst das Grid wieder in der Reihenfolge der sortierten Liste. Trick dabei ist, dass der einzelne Listeneintrag aus Zelle der zu sortierenden Spalte+Trenner+gesamte Zeile aufgebaut ist. Nach Sortierung der Liste wird das Grid neu gefüllt, aber natürlich nur mit dem Listeninhalt nach dem Trenner.

Wenn du das verstanden hast, müsstest du den Fehler auch finden können.

bl3nder 28. Aug 2008 10:58

Re: Stringgrid sortieren
 
Hmm anscheinend doch nich ganz verstanden, weil ich nicht draufkomme.

Delphi-Quellcode:
// MyString = 'xyz@INHALT'
bla := Copy(MyString, (ThePosition + 1), Length(MyString)); // bla = INHALT
Wo fehlt da jetz ein Operator ?

Hansa 28. Aug 2008 11:35

Re: Stringgrid sortieren
 
Sagen wirs mal knapp : mir gefällt der Source überhaupt nicht. Schon erstaunlich, dass solche Code-Fetzen jahrzehntelang im Internet rumschwirren. Da wird irgendein String zusammengebaut, sortiert und wieder zerlegt mit dem @. Nene.

IMHO ist es so besser : definiere ein TObject mit den Daten. Von mir aus so etwas :

Delphi-Quellcode:
TsgDaten = class(TObject)
  Spalte1 : string;
  Spalte2 : integer;
...
end;
Diese Objekte kommen nun in eine TObjectList. Und diese wird sortiert. Ergebnis dann wieder ins Stringgrid verfrachten.

bl3nder 28. Aug 2008 12:12

Re: Stringgrid sortieren
 
Das könnte ich mal probieren, allerdings müsste ich diese ObjectList beim Befüllen des Grids erstellen und beschreiben.
Das ist bei meinem Code relativ viel Arbeit, die ich mir auch sicher machen werde.

Trotzdem wüsste ich noch gerne wo jetzt der Fehler bei der Copy Methode ist.



Edit: Bei der Objectlist Methode hab ich das Problem, dass mein StrinGrid variable Spalten hat. Sprich der Inhalt einer Spalte ändert sich und die Anzahl der Spalten auch..


Ich wäre mit der schlechten alten SortStringGrid Funktion relativ glücklich :/

Hansa 28. Aug 2008 12:24

Re: Stringgrid sortieren
 
Zitat:

Zitat von bl3nder
Das ist bei meinem Code relativ viel Arbeit..Trotzdem wüsste ich noch gerne wo jetzt der Fehler bei der Copy Methode ist.

Was ist jetzt mehr Arbeit ? Das richtig zu machen, oder einen Fehler in fremdem Source zu suchen und den noch versuchen zu verstehen ? :shock:

Statt des Stringgrids füllst du die ObjectListe gleich mit den richtigen Typen, statt die Beschränkung auf Strings per StringListe hinzunehmen und die Dinger zu zerpflücken, Typumwandlung etc. Gemeinsam haben beide Verfahren, irgendeine Liste zu füttern. Erst danach kommt das Stringgrid ins Spiel !

Hawkeye219 28. Aug 2008 12:27

Re: Stringgrid sortieren
 
Hallo bl3nder,

ich kann verstehen, dass du den Fehler aufdecken möchtest. Nur so kannst du verhindern, dass er dir in Zukunft noch einmal passiert.

Hast du in der Unit eine Variable mit Namen Copy vereinbart? Das würde die Fehlermeldung erklären.

Gruß Hawkeye

bl3nder 28. Aug 2008 13:18

Re: Stringgrid sortieren
 
Zitat:

Zitat von Hawkeye219
Hallo bl3nder,

ich kann verstehen, dass du den Fehler aufdecken möchtest. Nur so kannst du verhindern, dass er dir in Zukunft noch einmal passiert.

Hast du in der Unit eine Variable mit Namen Copy vereinbart? Das würde die Fehlermeldung erklären.

Gruß Hawkeye

Vielen Dank, daran lags !!!

Eine Frage habe ich noch, ist zwar Off Topic aber es gibt dazu schon zu viele Threads, ich checks trotzdem nicht.

Mein Code sieht jetzt so aus:

Delphi-Quellcode:
// sort descending
function TForm1.StringListSortCompare(List: TStringList; Index1, Index2: Integer): Integer;
begin
  Result := AnsiCompareText(List[Index2], List[Index1]);
end;


procedure TForm1.SortStringGrid(var GenStrGrid: TStringGrid; ThatCol: Integer);
const
  // Define the Separator
  TheSeparator = '@';
var
  CountItem, I, J, K, ThePosition: integer;
  MyList: TStringList;
  MyString, TempString: string;
begin
  // Give the number of rows in the StringGrid
  CountItem := GenStrGrid.RowCount;
  //Create the List
  MyList       := TStringList.Create;
  MyList.Sorted := False;
  try
    begin
      for I := 1 to (CountItem - 1) do
        MyList.Add(GenStrGrid.Rows[I].Strings[ThatCol] + TheSeparator +
          GenStrGrid.Rows[I].Text);
      //Sort the List












      Mylist.CustomSort(StringListSortCompare); // [Pascal Fehler] Search.pas(762): E2009 Inkompatible Typen: 'Reguläre Prozedur und Methodenzeiger'












      for K := 1 to Mylist.Count do
      begin
        //Take the String of the line (K – 1)
        MyString := MyList.Strings[(K - 1)];
        //Find the position of the Separator in the String
        ThePosition := Pos(TheSeparator, MyString);
        TempString := '';
        {Eliminate the Text of the column on which we have sorted the StringGrid}
        TempString := Copy(MyString, (ThePosition + 1), Length(MyString));
        MyList.Strings[(K - 1)] := '';
        MyList.Strings[(K - 1)] := TempString;
      end;

      // Refill the StringGrid
      for J := 1 to (CountItem - 1) do
        GenStrGrid.Rows[J].Text := MyList.Strings[(J - 1)];
    end;
  finally
    //Free the List
    MyList.Free;
  end;
end;


procedure TForm1.GridMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
Var
  i,breite,spalte:Integer;
begin
if y<=Grid.RowHeights[0] then
begin
  breite:=0;
  For i:=0 To Grid.ColCount-1 Do
  Begin
    breite:=breite+Grid.ColWidths[i];
    if breite>x Then
    Begin
      spalte:=i;
      Break;
    end;
  end;
  SortStringGrid(Grid, spalte);
end;
end;

In allen Beispielen die ich finde wurde auch so eine komische Funktion geschrieben, die einen Integer zurückliefert.
Wenn ich nun der CustomSort Funktion statisch eine "1" verpasse dann meckert er
Zitat:

[Pascal Fehler] Search.pas(762): E2010 Inkompatible Typen: 'TStringListSortCompare' und 'Integer'
. Was ich widerrum nicht ganz verstehe, weil die Funktion

TForm1.StringListSortCompare(List: TStringList; Index1, Index2: Integer): Integer;

Ja auch eine Integer zurückliefert..

Auch in allen Beispielen.

DeddyH 28. Aug 2008 13:28

Re: Stringgrid sortieren
 
Der Fehler liegt hier darin, dass Du keine Funktion, sondern eine Methode deklariert hast.
Delphi-Quellcode:
function StringListSortCompare(List: TStringList; Index1, Index2: Integer): Integer;
Das TForm1 muss weg.

bl3nder 28. Aug 2008 13:48

Re: Stringgrid sortieren
 
Danke,

Jetzt kann ich aber in der Funktion keine globalen Variablen mehr benutzen, in der ich bspw. speichern konnte, ob zuletzt ascending oder descending gesucht wurde.

Wenn ich nun auf meine Fixed Row klicke im StringGrid dann wird immer nur in eine Richtung sortiert, es sollte aber so wie bei Windows funktionieren, dass beim erneuten Klicken auf die fixed row, die Sortierung umgedreht wird.

Wie realisiere ich das jetzt mit Customsort und diesem komischen Paramenter ?


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:19 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz