Tri d'un StringGrid sur base d'une colonne contenant des nombres [Résolu]

PhilLu 248 Messages postés lundi 9 novembre 2009Date d'inscription 27 décembre 2017 Dernière intervention - 4 juin 2013 à 22:30 - Dernière réponse : PhilLu 248 Messages postés lundi 9 novembre 2009Date d'inscription 27 décembre 2017 Dernière intervention
- 7 juin 2013 à 16:37
Bonsoir,
Je doit trier un stringgrid sur base d'une colonne contenant des nombres.
Voici mon code:
repeat
swap:=False;
for j := 1 to 100 do
if StrToInt(StringGrid2.Cells[11,j])> StrToInt(StringGrid2.Cells[11,j+1]) then
begin
tempstr:=StringGrid2.Rows[j];
StringGrid2.Rows[j] :=StringGrid2.Rows[j+1];
StringGrid2.Rows[j+1]:=tempstr;
swap:=true;
end;
until swap;
Malheureusement, nok et en plus des doublons
Je sêche!!!
Help
Afficher la suite 

20 réponses

Répondre au sujet
solilog 273 Messages postés samedi 13 juin 2009Date d'inscription 18 avril 2015 Dernière intervention - 6 juin 2013 à 14:01
+1
Utile
Salut tous,
C'est le rows[] qui déconne, mais le tri est bon. Essaye ca:

Pour cantador je vais mettre des balises, y va pa me filer des baffes quand même, j'en reçois déjà assez comme çà. Mais c'est la 1ere fois que je vois qu'il y a des balises. Je me demandais bien pourquoi les espaces à gauche de mon code n'apparaissait jamais.



procedure TForm1.Button1Click(Sender: TObject);
var x, y, z:integer;
tmpstr : array[0..100] of string;
begin
with gr1 do begin
for x:= 1 to rowcount -1 do
for y := 1 to rowcount-x do
if strtoint(cells[1, y]) > strtoint(cells[1, y+1]) then
for z := 0 to colcount-1 do begin
tmpstr[z] := cells[z,y];
cells[z,y] := cells[z, y+1];
cells[z, y+1] := tmpstr[z];
end;
end; end;




Voilà, en plus j'ai testé sur un stringgrid, j'ai vraiment du temps à perdre.
Ca devrait aller là, non ?
Le tri, c'était il y a ... 40 ans, oui 40 (ou là là, je me fais vieux)

solilog
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de solilog
solilog 273 Messages postés samedi 13 juin 2009Date d'inscription 18 avril 2015 Dernière intervention - 5 juin 2013 à 00:02
0
Utile
Salut,
un tri se fait avec 2 for imbriqués (au moins)

procedure tri;
var x, y : integer;
tmp : string;
begin
for x := 1 to 100-1 do
for y := 1 to 100-x do
if StrToInt(StringGrid2.Cells[11, y])> StrToInt(StringGrid2.Cells[11, y+1])
begin
tmp := StrToInt(StringGrid2.Cells[11, y];
StrToInt(StringGrid2.Cells[11, y] := StrToInt(StringGrid2.Cells[11, y+1];
StrToInt(StringGrid2.Cells[11, y+1] := tmp;
end;
end;

Bien que ce tri ne soit pas performant, il fonctionne.
Mais ce qui me semble bizarre, tu veux trier uniquement la col "i1" et laisser toutes les autre colonnes dans l'état. Ca va mixer les lignes.
Bizarre, vous avez dit bizarre ...

Bonne chance.

solilog
Commenter la réponse de solilog
PhilLu 248 Messages postés lundi 9 novembre 2009Date d'inscription 27 décembre 2017 Dernière intervention - 5 juin 2013 à 06:41
0
Utile
Super, merci!
Je trie toute la ligne puisque je permute StringGrid2.rows[j] et StringGrid2.rows[j+1]
Mais sur base des valeurs de la colonne 11 (numérique)
Commenter la réponse de PhilLu
solilog 273 Messages postés samedi 13 juin 2009Date d'inscription 18 avril 2015 Dernière intervention - 5 juin 2013 à 10:02
0
Utile
Bonjour,

Je t'encourage à regarder dans le rep demo, il y a un folder "Threads" où il y a 3 exemples de tri, c'est un bon tutoriel pour comprendre les tris.
Si la rep te convient, pense à accepter et ainsifermer cette discussion.

solilog
Commenter la réponse de solilog
PhilLu 248 Messages postés lundi 9 novembre 2009Date d'inscription 27 décembre 2017 Dernière intervention - 5 juin 2013 à 21:31
0
Utile
Merci mais où est le répertoire démo?
Commenter la réponse de PhilLu
PhilLu 248 Messages postés lundi 9 novembre 2009Date d'inscription 27 décembre 2017 Dernière intervention - 5 juin 2013 à 22:50
0
Utile
Ben non, pas mieux, aucun tri cette fois!!!

for x := 1 to 100-1 do
for y := 1 to 100-x do
if StrToInt(StringGrid2.Cells[11, y])> StrToInt(StringGrid2.Cells[11, y+1]) then
begin
tempstr:=StringGrid2.Rows[j];
StringGrid2.Rows[j] :=StringGrid2.Rows[j+1];
StringGrid2.Rows[j+1]:=tempstr;
end;
Commenter la réponse de PhilLu
solilog 273 Messages postés samedi 13 juin 2009Date d'inscription 18 avril 2015 Dernière intervention - 6 juin 2013 à 08:02
0
Utile
Salut,

Tu veux des baffes ? (désolé) Il faut regarder mon code et réfléchir un peu, non ? Mon tri je l'ai testé sur un tableau et pas sur un stringgrid. Les boucles sont faites avec x et y et ensuite swap avec des Row[j] et row[j+1]. Remplace les j par des y et tu verras, la révélation viendra:

if StrToInt(StringGrid2.Cells[11, y])> StrToInt(StringGrid2.Cells[11, y+1]) then
begin
tempstr:=StringGrid2.Rows[y];
StringGrid2.Rows[y] :=StringGrid2.Rows[y+1];
StringGrid2.Rows[y+1]:=tempstr;
end;
M'enfin, t'avais pas vu ça !!! Ne ferais-tu pas partie des partisans du copier/coller sans réfléchir ? Ce coup-ci tu devrais t'en sortir. (faut tout leur dire à ces mômes)

A propos du répertoire demo, il doit être dans le rep delphi. Si tu ne l'as pas, fais-moi un mail je t'enverrai le code des 3 tris.
Bonne journée.

solilog
Commenter la réponse de solilog
PhilLu 248 Messages postés lundi 9 novembre 2009Date d'inscription 27 décembre 2017 Dernière intervention - 6 juin 2013 à 08:34
0
Utile
Oui, j'avais déjà corrigé bien sûr mais je ne t'ai pas envoiyé le bon code
Avec le y, j'obtiens un tri mais me génère pleins de doublons???
J'ai tenté des motifs mais sans meilleur résultat...
Commenter la réponse de PhilLu
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 6 juin 2013 à 10:31
0
Utile
Bonjour,

@solilog :

Pour une bonne communication, il est nécessaire de mettre le code proposé
à l'intérieur des balises prévues à cet effet.

sinon, les baffes c'est pour toi..


cantador
Commenter la réponse de cs_cantador
solilog 273 Messages postés samedi 13 juin 2009Date d'inscription 18 avril 2015 Dernière intervention - 6 juin 2013 à 14:02
0
Utile
Mais, la balise ne marche pas!!! la prochaine fois j'en mettrai pas, tant pis pour les baffes.
Commenter la réponse de solilog
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 6 juin 2013 à 15:13
0
Utile
mais si mais si..

tu n'auras qu'une toute petite claque..


et pour les tris dans les stringgrid, cette question a été traitée
il y a belle lurette sur le site et on trouve plusieurs sources
traitant du sujet.

cantador
Commenter la réponse de cs_cantador
PhilLu 248 Messages postés lundi 9 novembre 2009Date d'inscription 27 décembre 2017 Dernière intervention - 6 juin 2013 à 19:38
0
Utile
Salut Solilog!
En effet c'est ok!!!
Il est vrai que je n'ai pas cherché du côté de la permutation de ligne,
StringGrid2.Rows[j] :=StringGrid2.Rows[j+1];

je cherchais (en vain) dans une autre direction (le tri)
Je ne comprend pas pourquoi cette permutation ne fonctionne pas, elle semble être correcte non?
Encore merci!
et bonne soirée!!!
Commenter la réponse de PhilLu
solilog 273 Messages postés samedi 13 juin 2009Date d'inscription 18 avril 2015 Dernière intervention - 6 juin 2013 à 20:34
0
Utile
PhiLU

Pour terminer là-dessus il faut utiliser Cols[y] et pas Rows[y], eh oui. Tiens, je viens aussi d'apprendre qq'chose.
- Rows[y] c'est le contenu de toutes les LIGNES de la colonne y
- Cols[y] c'est le contenu de toutes les COLONNES de la ligne y
Pas clairement dit dans la doc mais après un petit test c'est çà. Donc dans ton cas, tu dois utiliser un tmpstr : tStrings et faire la permutation avec des Cols[].
Tu peux fermer le ticket si pas encore fait.

solilog
Commenter la réponse de solilog
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 7 juin 2013 à 12:48
0
Utile
une autre solution proposée par Cirec, très performante,
consiste à utiliser des tableaux de pointeurs qu'il a donnée
dans un de ces posts assez récemment.

cantador
Commenter la réponse de cs_cantador
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 7 juin 2013 à 13:36
0
Utile
un code signé Fobec :

procedure SortStringGrid( var GenStrGrid: TStringGrid; ThatCol: integer);
const
TheSeparator = '@';
var
CountItem, I, J, K, ThePosition: integer;
MyList: TStringList;
MyString, TempString: string;
begin
CountItem := GenStrGrid.RowCount;
MyList := TStringList.Create;
MyList.Sorted := False;
try
begin
for I := 1 to (CountItem - 1) do
MyList.Add(GenStrGrid.Rows[I].Strings[ThatCol] + TheSeparator +
GenStrGrid.Rows[I].Text);
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;

for J := 1 to (CountItem - 1) do
GenStrGrid.Rows[J].Text := MyList.Strings[(J - 1)];
end;
finally
MyList.Free;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
//trier le Stringgrid d'après la première colonne
SortStringGrid(StringGrid1, 1);
end; 



cantador
Commenter la réponse de cs_cantador
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 7 juin 2013 à 13:37
0
Utile
un tuto signé Castelain :

TRI SG


cantador
Commenter la réponse de cs_cantador
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 7 juin 2013 à 13:44
0
Utile
Et puis cette unité aussi, pas mal :

unit U_Gridsort;

{Sample program to sort rows of a stringgrid based on any selected column}

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Grids, StdCtrls;

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure SortGrid(Grid : TStringGrid; SortCol:integer);
  end;

  var
  Form1: TForm1;

implementation

{$R *.DFM}

{************** SortGrid *************}
procedure Tform1.Sortgrid(Grid : TStringGrid; SortCol:integer);
{A simple exchange sort of grid rows}
var
   i,j : integer;
   temp:tstringlist;
begin
  temp:=tstringlist.create;
  with Grid do
  for i := FixedRows to RowCount - 2 do  {because last row has no next row}
  for j:= i+1 to rowcount-1 do {from next row to end}
  if AnsiCompareText(Cells[SortCol, i], Cells[SortCol,j]) > 0
  then
  begin
    temp.assign(rows[j]);
    rows[j].assign(rows[i]);
    rows[i].assign(temp);
  end;
  temp.free;
end;


procedure TForm1.FormCreate(Sender: TObject);
var
  i,j:integer;
  totwidth:integer;
begin
  with stringgrid1 do
  begin
    {assign some random numbers}
    for j := 1 to rowcount-1 do
    for i:= 1 to colcount-1 do
    cells[i,j]:=format('%3d',[random(1000)]);
    {Add row labels}
    for i:= 1 to rowcount-1 do cells[0,i]:='Row '+ format('%2d',[i]);
    {Add column labels and change column widths}
    totwidth:=0;
    for i:= 0 to colcount-1 do
    begin
      cells[i,0]:='Column '+ inttostr(i+1);
      {vary column widths for testing}
      colwidths[i]:=defaultcolwidth+random(48);
      inc(totwidth,colwidths[i]);
    end;
    {adjust grid width so that all column are visible}
    width:=totwidth+(colcount+3)*gridlinewidth;
  end;
end;


{************ StringgridMouseUp **************}
procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  c,j:integer;
  rect:trect;
begin
  with stringgrid1 do
  if y<rowheights[0] then   {make sure row 0 was clicked}
  begin
    for j:= 0 to colcount-1 do {determine which column was clicked}
    begin
      rect := cellrect(j,0);
      if (rect.Left < x) and (rect.Right> x) then
      begin
        c := j;
        break;
      end;
    end;
    sortgrid(stringgrid1,c);
  end;  
end;


end.


cantador
Commenter la réponse de cs_cantador
solilog 273 Messages postés samedi 13 juin 2009Date d'inscription 18 avril 2015 Dernière intervention - 7 juin 2013 à 14:52
0
Utile
Cantador,
Moi je m'arrête là avec le post de PhiLU. Je lui ai répondu, il doit pouvoir s'en sortir. J'ai quand même appris qq'cgose (grid.cols[y] est une ligne et rows[] une colonne), même mon help est faux. J'ai pas que çà à faire mon 400 me réclame (AS/400). En fait je réponds à des post delphi quand je suis en déplacement 1 sem/2, pour tuer la solitude et l'ennui.

@PhiLU, c'est bon là, ferme ce post, sinon cantador va nous noyer sous 1000 lignes de code.

salut à tous.

solilog
Commenter la réponse de solilog
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 7 juin 2013 à 15:28
0
Utile
aucun reproche à solilog..
je dirai même bravo pour ta participation !

et tu as raison, Philu a de quoi s'occuper désormais
et du pain sur la planche.

cantador
Commenter la réponse de cs_cantador
PhilLu 248 Messages postés lundi 9 novembre 2009Date d'inscription 27 décembre 2017 Dernière intervention - 7 juin 2013 à 16:37
0
Utile
Merci pour vos exemples et détails!!!
J'ai trouvé mon "bonheur" avec le code de Solilog!
Très bon week-end de code!!!
PhilLu
Commenter la réponse de PhilLu

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.