ListView und AlphaSort()



  • Hallo!

    Ich arbeite seit ein paar Tagen mit dem bcb6. Iregndwie funktioniert AlphaSort() nicht ganz richtig....
    Folgendes: Ich stelle in einer ListView Daten dar. ViewStyle steht auf vsReport. Die erste Spalte (Caption) enthält ein Datum. Die weiteren Spalten enthalten Texte. Nach klick auf einer Spaltenüberschrift soll nach dieser Spalte sortiert werden. Beim 1. Klick aufsteigend, bei nochmaligem Klick dann absteigend. Das geht auch einwandfrei. ich möchte nun die Sortiermöglichkeiten auch als Menüpunkt anbieten. Das ist das Problem.... Nach KLick im Menü auf "Datum aufwärts" funktionierts. Wenn ich aber "Datum abwärts" im Menü betätige gehts nicht!!!!!!

    Hier mein Code:

    void __fastcall TForm1::ListView1ColumnClick(TObject *Sender,
          TListColumn *Column)
    {
          Einstell.setsortSpalte(Column->Index);
        if (Einstell.getsortSpalte() == SpDatum) 
        {
          if (Einstell.getSort() == DateUp )
            Einstell.setSort(DateDown);
          else
            Einstell.setSort(DateUp);
        }
        else
        {
          if (Einstell.getSort() == AlphaUp )
            Einstell.setSort(AlphaDown);
          else
            Einstell.setSort(AlphaUp);
        }
    
        ListView1->AlphaSort();
        //((TCustomListView *)Sender)->AlphaSort();
    }
    

    Der Code entspricht in etwa dem aus der Hilfe vom BCB. Das OnCompare- Ereignis sieht dann so aus:

    void __fastcall TForm1::ListView1Compare(TObject *Sender, TListItem *Item1,
          TListItem *Item2, int Data, int &Compare)
    {
          if (Einstell.getsortSpalte() == SpDatum)         //Sortierung nach Datum
          { 
            //Sortierung nur nach Monat und Tag
            TDateTime *date1 = &(StrToDate(Item1->Caption) );
            TDateTime *date2 = &(StrToDate(Item2->Caption) );
            unsigned short y1,y2,m1,m2,d1,d2;
            date1->DecodeDate(&y1,&m1,&d1);
            date2->DecodeDate(&y2,&m2,&d2);
            y1 = y2 = 2003;                   //?!? Bei Angabe 1900 stimmts nicht
            date1 = new TDateTime(y1,m1,d1);
            date2 = new TDateTime(y2,m2,d2);
            AnsiString str1;
            str1.sprintf("%.0f",*date1);
            AnsiString str2;
            str2.sprintf("%.0f",*date2);
            delete date1;
            delete date2;
            if ( Einstell.getSort() == DateUp)
            {
              Compare = CompareText(str1, str2 );  // aufwärts 0->9
            }
            else
            {
              Compare -= CompareText(str1, str2);  // abwärts 9->0
            }
          }
          else                            //sortierung Alphabetisch
          {
            if (Einstell.getSort() == AlphaUp)  // aufwärts A->Z
            {  
              int subitem = Einstell.getsortSpalte() -1;
              Compare = CompareText(Item1->SubItems->Strings[subitem],
                                Item2->SubItems->Strings[subitem] );
            }
            else                                // abwärts Z->A
            {  
              int subitem = Einstell.getsortSpalte() -1;
              Compare -= CompareText(Item1->SubItems->Strings[subitem],
                                Item2->SubItems->Strings[subitem] );
            }
    
          }
    }
    

    Die Clickereignisse für das Menü:

    //Menü "Termine->Sortieren->Datum aufsteigend"
    // und PopupMenü
    void __fastcall TForm1::DatumAufsteigend1Click(TObject *Sender)
    {
        Einstell.setsortSpalte(SpDatum);
        Einstell.setSort(DateUp);
        /*TListColumn *col = ListView1->Column[0];  //geht auch damit nicht
        ListView1ColumnClick(ListView1, col);*/
        ListView1->AlphaSort();
    }
    //---------------------------------------------------------------------------
    //Menü "Termine->Sortieren->Datum absteigend"
    // und PopupMenü
    void __fastcall TForm1::DatumAbsteigend1Click(TObject *Sender)
    {
        Einstell.setsortSpalte(SpDatum);
        Einstell.setSort(DateDown);
        ListView1->AlphaSort();
        //ListView1->UpdateItems(0,ListView1->Items->Count);//nützt nichts
        /*TListColumn *col = ListView1->Column[0];          //geht damit auch nicht
        ListView1ColumnClick(ListView1, col);*/
    }
    

    Also, die letzte Methode wird nach Klick auf Menü "Datum absteigend" durchlaufen, stellt ein paar Werte ein, und ruft dann AlphaSort() auf. Mit dem Debugger konnte ich feststellen, das in der OnCompare Behandlungsroutine auch der richtige Teil abgearbeitet wird. Nämlich:

    else
            {
              Compare -= CompareText(str1, str2);  // abwärts 9->0
            }
    

    Doch stimmt das Ergebnis nicht!!!! Die Darstellung der Zeilen wird einfach umgedreht. Wenn ich vorher nach Spalte 3 sortiert habe, wird nach Klick auf Menü "Datum abwärts" zwar sortiert, aber Spalte 3, nicht Spalte 1! Es spielt dabei auch keine Rolle, welche Angaben ich für SortType mache (stNone,stData, stBoth). Klicke ich auf Menü "Datum aufwärts" macht er es richtig....
    Was habe ich da noch nicht verstanden??? Oder ist es ein Fehler in AlphaSort()?

    Hoffe mein Problem verständlich dargestellt zu haben.



  • Hallo!

    Komisch.... immer wenn ich eine Frga stelle, bekomme ich keine Antwort 😕 !
    Na ja, vielleicht sind meine Fragen zu doof ????

    Mache jetzt 'ne eigene Sortierroutine....



  • Schon versucht, über das Menu einfach einen entsprechenden ColumnClick auszulösen?



  • Hallo Jansen!

    Wie meinst Du das?
    Habs schon so versucht (im OnClickEreignis für das Menü; siehe Code oben):

    TListColumn *col = ListView1->Column[0]; 
        ListView1ColumnClick(ListView1, col);     //Aufruf von OnColumnClick
    

    aber kein erfolg!

    Im Objektinspector wird das "OnColumnClick" Ereignis bei dem "OnClick" Ereignis nicht aufgeführt.

    Oder meinst Du noch was anderes?

    Thanks



  • Oops, den Kommentar hatte ich übersehen, genau das meinte ich.
    Was bedeutet da "geht damit auch nicht"? Ergibt das auch nur das falsche Ergebnis oder wird der ColumnClick gar nicht ausgeführt?



  • Hallo Jansen!

    Fehler(?) gefunden:

    Irgendwie funktioniert die Negierung des Rückgabewertes von CompareText nicht...

    else
            {
              Compare -= CompareText(str1, str2);  // abwärts 9->0
            }
    

    Compare erhält damit Werte, die jenseits von gut und böse sind... Nach umstellung auf:

    else
            {
              Compare = -1*(CompareText(str1, str2) );  // abwärts 9->0
            }
    

    gehts tadellos....

    Bleibt nur die Frage warum? Liegts vielleicht daran, das str1 und str2 in Strings gewandelte Zahlenwerte sind????

    Was bedeutet da "geht damit auch nicht"? Ergibt das auch nur das falsche Ergebnis oder wird der ColumnClick gar nicht ausgeführt?

    ColumnClick wird immer ausgeführt....

    Danke nochmal (obwohl Du mir nicht helfen konntest). Aber vielleicht ist das ja was für die FAQ?



  • Hmm, das '-=' kam mir gleich spanisch vor, das ist doch keine Negation. 😉

    Das Problem wird sein, dass Compare erstmal keinen definierten Wert hat, du von diesem undefinierten Wert das CompareText()-Ergebnis abziehst und das Resultat zurückgibst.

    Für die Negation kannst du übrigens auf das '1*' verzichten, es reicht aus, das Minuszeichen voranzustellen.

    PS. Einen vergleichbaren FAQ-Beitrag gibt es zum Thema 'StringList sortieren'.



  • void __fastcall TfrmStamm::tlvCompare(TObject *Sender, TListItem *Item1,
                                                        TListItem *Item2, int Data, int &Compare)
    {
        TListView *pLV = dynamic_cast<TListView *>(Sender);
    
        if(iCol == 0)
        {
            if(pLV->Tag == 1)    //ASC
            {
                Compare = AnsiCompareStr(Item1->Caption,Item2->Caption);
            }
            else              //DESC
            {
                Compare = -AnsiCompareStr(Item1->Caption,Item2->Caption);
            }
        }
        else
        {
            if(pLV->Tag == 1) //ASC
            {
                Compare = AnsiCompareStr(Item1->SubItems->Strings[iCol-1], Item2->SubItems->Strings[iCol-1]);
            }
            else              //DESC
            {
                Compare = -AnsiCompareStr(Item1->SubItems->Strings[iCol-1], Item2->SubItems->Strings[iCol-1]);
            }
        }
    }
    //---------------------------------------------------------------------------
    

    Edit:
    Überlanges Hilfe-Zitat entfernt.

    [ Dieser Beitrag wurde am 24.01.2003 um 16:43 Uhr von Jansen editiert. ]



  • Hi!

    Jup, alles klar....dachte ich hätte das so in der BCB Hilfe gesehen...

    Danke


Anmelden zum Antworten