Ordenar un TStringGrid por una determinada columna
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); |
Embarcadero MVP.
Analista y Programador de Sistemas Informáticos.
Estudios de Informática (Ingeniería Técnica Superior) en la UPC (Universidad Politécnica de Barcelona).
Llevo utilizando Delphi desde su versión 3. Especialista en diseño de componentes, Bases de Datos, Frameworks de Persistencia, Integración Continua, Desarrollo móvil,…
Mil Gracias.
Muy Util
Gracias por el procedimiento… Hoy 3 años despues me ha servido bastante….