Ordenar un TStringGrid por una determinada columna
jueves, 9 de octubre de 2008
2 comentarios
Procedimiento que muestra cómo ordenar un TStringGrid a partir de los datos de una columna. El texto está basado en esta página Web donde hay un algoritmo de ordenación. El problema es que sólo es para datos numéricos. En este truco he añadido un par de parámetros para poder definir columnas de otro tipo (u ordenación de otro tipo) y además marcar si que quiere de forma Ascendente o Descendente (que tampoco está en el truco original).
Yo he añadido métodos para ordenar por enteros y Float, aunque ampliando se pueden añadir para alguno más.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | // Ordena un TStringGrid. procedure SortStringGrid(var GenStrGrid: TStringGrid; ThatCol: Integer; ColData:TGridData=gdString; SortOrder:TSortOrder=soASC); const TheSeparator = '@'; var CountItem, I, J, K, ThePosition: integer; MyList: TStringList; MyString, TempString: string; str:string; vali:Integer; valf:Double; begin CountItem := GenStrGrid.RowCount; MyList := TStringList.Create; MyList.Sorted := False; try begin for I := 1 to (CountItem - 1) do begin Str := GenStrGrid.Rows[I].Strings[ThatCol]; if (ColData = gdInteger) then begin vali := StrToIntDef(Str, 0); Str := Format('%*d', [15,vali]); end; if (ColData = gdFloat) then begin valf := StrToFloat(Str); Str := Format('%15.2f',[valf]); end; MyList.Add(Str + TheSeparator + GenStrGrid.Rows[I].Text); end; Mylist.Sort; for K := 1 to Mylist.Count do begin MyString := MyList.Strings[(K - 1)]; 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; if (SortOrder = soASC) then begin for J := 1 to (CountItem - 1) do begin GenStrGrid.Rows[J].Text := MyList.Strings[(J - 1)]; end; end else begin for J := 1 to (CountItem - 1) do begin I := (CountItem - J); GenStrGrid.Rows[I].Text := MyList.Strings[(J - 1)]; end; end; end; finally MyList.Free; end; end; |
AÑADO: Me falta una cosa.
Además habrá que definir en la unit los dos tipos que se utilizan para la ordenación:
1 2 3 4 5 | Type //: Tipo de Dat de la columna por la que queremos ordenar. TGridData = (gdString, gdInteger, gdFloat); //: Tipos de ordenación. TSortOrder = (soASC, soDESC); |