StringGrid - sortieren I



  • Hi

    kann man irgendwie StringGrid Reihen nach dem Wert der jeweils dritten Spalte ordnen? Oder geht es auch mit StringLists nach dem wert des jeweils dritten strings?

    [ Dieser Beitrag wurde am 11.06.2002 um 15:45 Uhr von Jansen editiert. ]



  • Hier hast du mal ein BubbleSort, welches direkt in die StringGrid-Rows schreibt (dementsprechend langsam ist es auch images/smiles/icon_smile.gif).

    void GridSort(TStringGrid *grid, int ColToSortBy, bool desc)
    {
      int fr = grid->FixedRows; // zum Ausschluss der FixedRows
    
      for (int j = grid->RowCount-fr; j > 0; j--)
      {
        for (int i = 0; i < j; i++)
        {
          // zwei Zelleninhalte der gewählten Spalte für den
          // Vergleich vorbereiten
          String str1, str2 = "0";
          str1 = grid->Cells[ColToSortBy][i+fr];
          if (i+1 < grid->RowCount - fr) // "List out of bounds" vermeiden
            str2 = grid->Cells[ColToSortBy][i+fr+1];
    
          int a, b;
          if (desc) // absteigend sortieren
          {
            a = str1.ToInt();
            b = str2.ToInt();
          }
          else      // aufsteigend sortieren
          {
            a = str2.ToInt();
            b = str1.ToInt();
          }
    
          // Vergleich der Zelleninhalte ...
          if (a < b && i+1 < grid->RowCount-fr)
          { // ... und Vertauschen der zugehörigen Zeilen(inhalte)
            String tmp = grid->Rows[i+fr]->CommaText;
            grid->Rows[i+fr]->CommaText = grid->Rows[i+fr+1]->CommaText;
            grid->Rows[i+fr+1]->CommaText = tmp;
          }
        }
      }
    }
    


  • Eleganter und schneller würe es, wenn du ne Klasse von TStringGrid ableitest und dann die als protected deklarierte Methode MoveRow benutzt. Ist ( hab ich nicht getestet) wahrscheinlich mehr als doppelt so schnell.



  • auf die geschwindigkeit kommt es mir eigentlich weniger an (es wird ja wohl nicht so lange dauern, 18 reihen zu ordnen).
    Ich hab aber noch ne frage zu jansens code:
    wenn ich deine methode in der header-datei so einbinden will:

    virtual void GridSort(TStringGrid *grid, int ColToSortBy, bool desc);
    

    kommt diese fehlermeldung bei der Kompilierung:
    [Linker Error] Undefined symbol TForm1::GridSort(Grids::TStringGrid*,bool) referenced from blablabla\UNIT1.OBJ



  • Eleganter und schneller würe es, wenn du ne Klasse von TStringGrid ableitest

    Noch eleganter und schneller wäre es, sich bei www.torry.net 'ne fertige Komponente runterzuladen, erweiterte Grids gibt's da ja wie Sand am Meer. images/smiles/icon_smile.gif

    eßer:
    Füge bei der Implementierung ein TForm1:: ein (oder wie immer deine Form heisst).

    void TForm1::GridSort(TStringGrid *grid, int ColToSortBy, bool desc)
    {
      // der Code
    }
    


  • Achso ich hatte TForm1:: vergessen.
    Danke!
    Funzt super!

    [ Dieser Beitrag wurde am 23.02.2002 um 12:11 Uhr von eßer editiert. ]



  • Was das Problem mit dem identischen Zelleninhalt betrifft: statt für jeden potentiellen zusätzlichen Fall eine weitere Abfrage einzubauen lässt sich das, wie so oft, eleganter und universeller mit einer Schleife lösen.

    Ersetz' mal in meinem obigen Beispiel den Abschnitt von zwei Zelleninhalte ... bis vor int a, b; mit folgendem Code:

    // Zwei Zelleninhalte der gewählten Spalte für den Vergleich vor-
          // bereiten.
          // Wenn beide Zellen gleich sind, statt dessen die entsprechenden
          // Zellen der nächsten rechtsliegenden Spalte für den Vergleich
          // heranziehen.
          String str1, str2 = "0";
          int Col = ColToSortBy;
          do
          {
            str1 = grid->Cells[Col][i+fr];
            if (i+1 < grid->RowCount - fr) // "List out of bounds" vermeiden
              str2 = grid->Cells[Col][i+fr+1];
    
            // Wenn rechts die letzte Spalte erreicht wurde, links bei der
            // ersten Spalte weitermachen, bis die ursprüngliche Spalte wieder
            // erreicht wird.
            if (Col < grid->ColCount-1)
              Col++;
            else
              Col = 0;
          }
          while (str1 == str2 && Col != ColToSortBy);
    

    [ Dieser Beitrag wurde am 02.05.2002 um 20:55 Uhr von Jansen editiert. ]


Anmelden zum Antworten