Hej,
Jeg har to "hovedklasser" som alle mine underklasser arver fra. Den ene 
er en dataklasse(arver fra TPersistent), det kunne eksempel være en 
vare, en kunde osv. Den anden hovedklasse er en listeklasse(arver fra 
TObjectList), denne indeholder så en liste af dataklasser, f.eks. en 
varelist, en kundeliste osv.
Da jeg bruger RaveReports til rapportgenerering vil jeg gerne kunne 
angive, fra Rave-rapporten, hvilken property i data-klassen som en given 
liste skal kunne sorteres efter. Da jeg gerne vil undgå at lave sorting 
for alle klasser og alle properties har jeg forsøgt at benytte mig af 
RTTI.
Jeg har lavet en metode i min listeklasse(TNPParentList.PrinterSetSort), 
denne metode kaldes fra Rave Reports når brugeren har sat en 
SortKey-property på et databand som henter data fra listen. Dette 
fungere fint, men idag spurgte en test-brugere så om: "Jeg vil gerne 
sortere efter FeltA _OG_ FeltB...i den rækkefølge...hvordan gør jeg 
det?"....øh...jeg forsøgte så at omskrive sortingsfunktionen til at 
understøtte dette, men det vil bare ikke som jeg vil. Nu har jeg så 
efterhånden stiret mig blind på det og mistænker nu Quicksort for ikke 
at kunne bruges til det jeg forsøger. Er der nogen der kan gennemskue om 
det er korrekt eller set hvor jeg har lavet fejlen?
Først en kildekoden:
**********
//Method to enable users to sort lists from a Rave-report
procedure TNPParentList.PrinterSetSort(Connection: TRvCustomConnection);
  //Compare-method for the Sort-function
  function SortCompare(Item1, Item2: Pointer): Integer;
  var
    Count, Loop: Integer;
    List: PPropList;
    objProp: TObject;
    SortLoop: integer;
  begin
    //Make sure we are reset
    SortLoop:=0;
    Result:=0;
    //Allocate space for properties of the data-class
    //Note: item1 and item2 will always be of the same class, so just 
use item1!
    Count := GetPropList(TNPParent(item1).ClassInfo, tkProperties, nil) 
;
    GetMem(List, Count * SizeOf(PPropInfo)) ;
    GetPropList(TNPParent(item1).ClassInfo, tkProperties, List);
    try
      //Loop as long as we does not have a difference in the sorting 
fields (...or aslong as we have fields to sort by!)
      while (result=0) and (SortLoop<TNPParent(Item1).SortingList.Count) 
do
      begin
        //Loop through the property-list of the data-class...
        for Loop := 0 to Pred(Count) do
        begin
          //Is this the right property to sort by?
          If TNPParent(Item1).SortingList[SortLoop] = List[loop]^.Name 
then
          begin
            //Make sure we sort the right way...only Integers, Strings 
and Floats at the moment!
            case List[Loop]^.PropType^.Kind of
              tkInteger: 
Result:=CompareValue(GetOrdProp(TNPParent(Item1),List[loop]^.Name),GetOrdProp(TNPParent(Item2),List[loop]^.Name));
              tkString,
              tkLString,
              tkWString: 
Result:=CompareText(GetStrProp(TNPParent(Item1),List[loop]^.Name),GetStrProp(TNPParent(Item2),List[loop]^.Name));
              tkFloat: 
Result:=CompareValue(GetFloatProp(TNPParent(Item1),List[loop]^.Name),GetFloatProp(TNPParent(Item2),List[loop]^.Name));
              else raise exception.create(Format(_('Cannot sort on field 
"%s", the format of the field is not supported! Please redefine 
sortfield!'),[TNPParent(Item1).SortingList[SortLoop]]));
            end;
            //No need to search any further! We found the right 
property!
            break;
          end;
          //showmessage(List[loop]^.Name+chr(13)+inttostr(loop)+chr(13)+inttostr(Pred(Count)));
          //Did we not find the property? If we are sorting on a 
sub-class we wont find it! e.g. "dataclass.dataclass.property"
          if loop=Pred(Count) then
          begin
            raise exception.create(Format(_('Cannot sort on field "%s", 
maybe a sub-field? Please redefine 
sortfield!'),[TNPParent(Item1).SortingList[SortLoop]]));
          end;
        end;
        //Goto the next sort-field...
        Inc(SortLoop);
      end;
    finally
      FreeMem(List, Count * SizeOf(PPropInfo))
    end;
  end;
var
  a: integer;
  TheSortList: TStrings;
  SortByFieldName: string;
begin
  //Get the name of the field which the list should be sorted...
  SortByFieldName:=Connection.ReadStr;
  //Create a list of strings(Since the "SortByFieldName" can be of the 
format "Field1 & Field2 & Field3..."
  TheSortList:=TStringlist.create;
  try
    //Loop through the string and find each field-name
    while pos('&',SortByFieldName)> 0 do
    begin
      TheSortList.Add(Trim(copy(SortByFieldName,1,pos('&',SortByFieldName)-2)));
      System.Delete(SortByFieldName,1,pos('&',SortByFieldName));
    end;
    //...remember to add the last field in the list(...and potential the 
only one!)
    TheSortList.Add(Trim(SortByFieldName));
    //Assign all the searchfields to each item (to be used in the 
SortCompare-method)
    for a:=0 to Self.Count-1 do
    begin
      Items[a].SortingList.Text:=TheSortList.Text;
    end;
  finally
    TheSortList.free;
  end;
  //Use the TList.Sort function to sort the list...
  Sort(@SortCompare);
end;
**********
Så problemet:
Say jeg søger på FeltA(en streng-type) og FeltB(en float-type), f.eks.:
1: "A" og 5,5
2: "B" og 1,0
3: "A" og 4,5
Så ville jeg forvente at den sorterede listen som 3-1-2:
3: "A" og 4,5
1: "A" og 5,5
2: "B" og 1,0
MEN dette er ikke tilfælde, den sortere ikke efter felter ud over den 
første:
1: "A" og 5,5
3: "A" og 4,5
2: "B" og 1,0
....min tanke er så: Jeg har mistænkt min do-while løkke for at være 
årsagen til problemet: altså det med at jeg kun kigger på de 
efterfølgende felter hvis det aktuelle felt er ens for item1 og item2. 
Men jeg kan ikke rigtigt gennemskue hvorfor det IKKE skulle virke. Jeg 
håbede derfor at der var nogle "søgehajer" herinde som kunne sige: "hør 
lige her unge mand, linje 7 er der helt i skoven!"...eller noget i den 
stil
PS: Jeg har brugt samme princip til at fortælle Rave hvilke felter der 
findes i data-klasserne og til at hente data ind i Rave fra 
listerne...Jeg synes selv det er suuuuper smart, men jeg kunne godt 
tænke mig at høre hvordan andre gør? Om jeg bare har opfundet den dybe 
tallerken igen....igen....?
MVH
  Thomas