Comment colorier une ligne de StringGrid quand la veluer d'une de ses cellules d

Résolu
Frank_klein Messages postés 34 Date d'inscription samedi 26 mars 2005 Statut Membre Dernière intervention 8 février 2022 - 30 juil. 2008 à 15:10
PhilLu Messages postés 251 Date d'inscription lundi 9 novembre 2009 Statut Membre Dernière intervention 11 mai 2021 - 19 nov. 2013 à 23:55
SALUT,


comment faire pour colorier une ligne d'une StringGrid lorsqu'une cellule depasse une certaine valeur, par exemple  si la ligne nr 4 possede un cellule avec une valeur superieure à 100 je veux que la ligne nr 4 soit la colorier en rouge, si cetet valeur est entre 50 et 100 je veux  la colorier en bleu et si c'est en dessous de 50 doit etre colorié en jaune. J'ai cherché sur le forum mais il n'y a aucun topic, aucun code qui soumet la couler à uen condition de valuer. J'ai vu d'autres procedure de coloriage mais aucune avec la conditio de la valeur des cellules.

Si vous ne asavez pas ne repondez pas, cela polue plus le forum qu'autre chose, on passe de page en page sur des suposés explicaiton qui ne sont que des embrouilles.


@+

18 réponses

Oniria Messages postés 292 Date d'inscription dimanche 14 mars 2004 Statut Membre Dernière intervention 18 décembre 2014 3
5 août 2008 à 11:40
Bonjour,

Je rapporte ma pierre à l'édifice. Les boucle for ne sont pas utiles. En effet, lorsqu'une case est modifiée, la fonction DrawCell est appelé donc le code devient :

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  i : integer;
  couleur : TColor;
begin
  ACol := 4;
  with StringGrid1 do
  begin
     // On récupére la valeur de la case qui nous intéresse pour la colorisation
     try
       i:=StrToInt(Cells[4, ARow]);
     except
       i:=0;
     end;
    // On fait les comparaison pour déterminer la couleur
    if i >= 100 then couleur:=clRed
      else
   if (i > 50) and (i< 100) then couleur:=clBlue
     else
    if i < =50 then couleur:=clYellow;
    // On affiche
    Canvas.Brush.Color := couleur;
    Canvas.FillRect(Rect);
    canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + 2, Cells[ACol, ARow]);
   
  end;
end;

Oniria
3
HAFTARIFOUAD Messages postés 256 Date d'inscription mercredi 5 septembre 2007 Statut Membre Dernière intervention 6 janvier 2011
30 juil. 2008 à 19:18
Bonjour

"Si vous ne savez pas ne repondez pas", je pense que ma réponse vous sera utile:

Dans l'event :DrawColumnCell double cliqez et saisissez ce code:

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
if not ( gdFocused in State ) then
  begin


    if (Table1.fields[i].AsInteger < 100) then ====== i:= l'index de votre champ qui contient les valeurs recherchées
       Dbgrid1.Canvas.Brush.Color :=  clWhite
    else
       Dbgrid1.Canvas.Brush.Color := clRed;
    Dbgrid1.DefaultDrawColumnCell(Rect,DataCol,Column,State);
 end;
end;

Bonne chance et plein de succès.
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
30 juil. 2008 à 19:48
bonsoir,

Fouad, c'est un stringgrid...

cantador
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
30 juil. 2008 à 21:09
unit Unit1;


interface


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


type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    procedure FormCreate(Sender: TObject);
    procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;


var
  Form1: TForm1;


implementation


{$R *.dfm}


procedure TForm1.FormCreate(Sender: TObject);
begin
  StringGrid1.Cells[2, 1] := '101';
  StringGrid1.Cells[4, 2] := '70';
  StringGrid1.Cells[3, 3] := '35';
end;


procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  i, j, k: integer;
begin
  with StringGrid1 do
  begin
    for i := 0 to ColCount - 1 do
      for j := 0 to RowCount - 1 do
        if Cells[i, j] <> '' then
        begin
          if StrToInt(Cells[i, j]) > 100 then
          begin
            for k := 0 to ColCount - 1 do
            begin
              Rect := CellRect(k, j);
              Canvas.Brush.Color := clRed;
              Canvas.FillRect(Rect);
              canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + 2, Cells[k, j]);
            end;
            break;
          end;
          if (StrToInt(Cells[i, j]) > 50) and (StrToInt(Cells[i, j]) < 100) then
          begin
            for k := 0 to ColCount - 1 do
            begin
              Rect := CellRect(k, j);
              Canvas.Brush.Color := clBlue;
              Canvas.FillRect(Rect);
              canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + 2, Cells[k, j]);
            end;
            break;
          end;
          if (StrToInt(Cells[i, j]) < 50)  then
          begin
            for k := 0 to ColCount - 1 do
            begin
              Rect := CellRect(k, j);
              Canvas.Brush.Color := clYellow;
              Canvas.FillRect(Rect);
              canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + 2, Cells[k, j]);
            end;
            break;
          end
        end;
  end;
end;


end.

cantador
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Frank_klein Messages postés 34 Date d'inscription samedi 26 mars 2005 Statut Membre Dernière intervention 8 février 2022
30 juil. 2008 à 22:09
Bonjour cantador,


votre exemple est le bon, effectivement il s'agit d'un StringGrid comme je le précisé au depart, autrement ça marche parfaitement, il faut juste faire debuter le compteur sur 1 et pas sur 0 si non cela efface le nom des colones et des lignes, (spécifique à mon programme). En mêm temps je peut dire que HAFTARIFOUAD par son erreur a anticipé un peu mes attentes, car j'ai l'intention de faire la même chose avec une DBGrid aussi.

Merci à tous les deux.

Frank
0
Frank_klein Messages postés 34 Date d'inscription samedi 26 mars 2005 Statut Membre Dernière intervention 8 février 2022
31 juil. 2008 à 12:05
Salut,

Je voudrais faire evoluer le code de cantador, à savoir, les cellules ne seront pas remplies lors de la creation du Form mais à travers une autre procedure qui prend les valerus d'un tableau,  en conclusion :

1- j'ai essayé d'appliquer le code de cantador dans ce cas de figure mais il y a un probeme,  les instructions "break" arrete le remplissage de plusieurs lignes, il s'arrete à une seulle ligne à colorier par couleur,

2- j'ai essayé d'enlever l'instruction "break" mais le porblme alros c'est le temps de traitement, ça bouffe tout la ressource du processeur, il parcout tous les cellules et je doit attendre pres d'une minute que les boucles sur les trois coulerus s'arretent.

3 - j'ai essayé d'alleger les calcul en verifiant la veleur "StringToInt" d'une seule cellule, en effet il ne me faut qu'une seule cellule à verifier si ele depasse 100 etc, mais le porblem est que ça bouffe toujours autant de ressource,


Je pense qu'il y a un problème au niveu des boucles, si quelqu'un a une idée pour eviter que le code boufe autant de memorie cela serait bien venue.

Merci


 
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
31 juil. 2008 à 17:32
Ce n'est plus du tout le même programme que tu demandes..
Donc, il faut revoir le code et l'adapter..

Il faut que tu précises exactement comment tu souhaites entrer les valeurs dans ton stringgrid en te servant :
d'une table, d'un ou plusieurs tableaux de ? (à préciser)

etc etc..

cantador
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
31 juil. 2008 à 21:14
Il faut aussi définir la règle de colorisation de la ligne:
car dans une ligne si tu as les trois conditions qui sont vraies :
quelle est la couleur de la ligne dans ce cas ?
le choix change toute la programmation..

cantador
0
Frank_klein Messages postés 34 Date d'inscription samedi 26 mars 2005 Statut Membre Dernière intervention 8 février 2022
31 juil. 2008 à 21:41
bonjour, voici le programme :

1. les données sont introduites à partir d'un tableau qui est remplit au fur et à mesure.
2. une fois le tableu remplit, il sera transféré dans la StringGrid et il n'y a que la valeur d'UNE SEULE CELLULE qui est verifié sur tous les lignes et ainsi une seule couleur possible sur la ligne en fontion de cette valeur. (StringGrid1.Cells[1, 5]  joursqu'à  StringGrid1.Cells[5, 5] )

Exemple, la StringGrid possede 5 lignes et 5 colones, je vais verifier dans la colone nr 5 sur TOUTES LES LIGNES:
a) -  si la velur qu'elle contient est soit inferieure à 50, alors cette ligne doit etre colorié en jaune, 
b) - si elle est superieur à 50 et infeireur à 100 alors colorier al ligne en bleu, 
c) - et si superieure à 100 alors  colorier la ligne en rouge.

Le code proposé precedament marche si je le met dans une procedure à part, mais les couleurs disapraissent quand le Form est desactivé, et si je le met sur  l'évenement "DrawCell" cela boufe toute la memoire car les boucles ne s'arrenet pas de tourner avant de faire le calcul sur toutes les colones, j'ai essayé de le "customiser "mais j'ai pas reussit. Merci.
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
31 juil. 2008 à 22:05
c'est plus simple encore :

unit Unit1;


interface


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


type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    procedure FormCreate(Sender: TObject);
    procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
  private
    { Déclarations privées }
    procedure Stockage;
  public
    { Déclarations publiques }
  end;


var
  Form1: TForm1;


const
   ColChiffre = 4;


implementation


{$R *.dfm}


procedure TForm1.Stockage;
var
  j: integer;
begin
  randomize;
    for j := 1 to StringGrid1.RowCount - 1 do
// ici il faut stocker les valeurs venant de ton tableau
      StringGrid1.Cells[ColChiffre, j] := IntToStr(random(120));
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  Stockage;
end;


procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  i, j, k: integer;
begin
  ACol := 4;
  with StringGrid1 do
  begin
    for j := 1 to RowCount - 1 do
        if Cells[ColChiffre, j] <> '' then
        begin
          if StrToInt(Cells[ColChiffre, j]) > 100 then
          begin
            for k := 1 to ColCount - 1 do
            begin
              Rect := CellRect(k, j);
              Canvas.Brush.Color := clRed;
              Canvas.FillRect(Rect);
              canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + 2, Cells[k, j]);
            end;
          end
          else
            if (StrToInt(Cells[ColChiffre, j]) > 50) and (StrToInt(Cells[ColChiffre, j]) < 100) then
            begin
              for k := 1 to ColCount - 1 do
              begin
                Rect := CellRect(k, j);
                Canvas.Brush.Color := clBlue;
                Canvas.FillRect(Rect);
                canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + 2, Cells[k, j]);
              end;
            end
            else
              if (StrToInt(Cells[ColChiffre, j]) < 50) then
              begin
                for k := 1 to ColCount - 1 do
                begin
                  Rect := CellRect(k, j);
                  Canvas.Brush.Color := clYellow;
                  Canvas.FillRect(Rect);
                  canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + 2, Cells[k, j]);
                end;
              end;
        end;
  end;
end;


end.

cantador
0
Frank_klein Messages postés 34 Date d'inscription samedi 26 mars 2005 Statut Membre Dernière intervention 8 février 2022
1 août 2008 à 11:57
merci cantador, ça marche, même si le code bouffe tojours un peu des ressources quand on met une stringgrid avec plus de 15 lignes cela prend un peu de temps, peut être que c'est du au type persistent de l'evenement de DarwCell, car losque j'applique le code sur une procedure ordinaire, cela ne prend pas du temps, ça se fait en une fraction de seconde, mais c'est pas trop genant, pour l'instant je vais le laisser comme ça. @ +
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
1 août 2008 à 14:31
j'ai pas tout testé..
et l'habitude veut que je me serve du OnDrawCell car il maintient les couleurs en place.

Mais si çà te convient tu peux déplacer le code de l'évènement
OnDrawCell dans une procédure..

Dans ce cas, attention, il faut que tu crée une variable
Recta : TRect;
et que tu le définisses car dans l'évènement, il est directement en paramètre !
ex:

procedure TForm1.Button1Click(Sender: TObject);
var
  Recta: TRect;
  ACol, ARow: integer;
begin
  for Acol := 0 to StringGrid1.ColCount - 1 do
    for ARow := 0 to StringGrid1.RowCount - 1 do
   begin
    Recta := StringGrid1.CellRect(ACol,ARow); 
    ----
    ----
    ----
    ----  
   end;
end;

A adapter bien sûr..

cantador
0
Frank_klein Messages postés 34 Date d'inscription samedi 26 mars 2005 Statut Membre Dernière intervention 8 février 2022
5 août 2008 à 13:20
bonjour Onoria, ton code resout mon problème, j'avait l'intention de reposter pour avoir une idée car cela relentissait trop le fontionnement du programme notament quand je charge un fichier Excel sur la stringgrid, donc bravo,  j'ai fait quelques modifications, sepcifiques à mon programme, car il m'effacait les ligens et les colones d'entete, docn j'ai comenté la ligne "ACol=4" et j'ai rajouté quelques evenments sur la mise en forme du texte de sortie

merci  
@+
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
5 août 2008 à 19:14
une petite amélioration évitant les messages d'erreurs :
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  i: integer;
  couleur: TColor;
begin
  ACol := 4;
  couleur := 0;
  with StringGrid1 do
  begin
     // On récupére la valeur de la case qui nous intéresse pour la colorisation
    if Cells[ACol, ARow] <> '' then
      i := StrToInt(Cells[ACol, ARow])
    else
      i := 0;
    // On fait les comparaison pour déterminer la couleur
    if i >= 100 then
      couleur := clRed
    else
      if (i > 50) and (i < 100) then
        couleur := clBlue
      else
        if i <= 50 then
          couleur := clYellow;
    // On affiche
    Canvas.Brush.Color := couleur;
    Canvas.FillRect(Rect);
    canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + 2, Cells[ACol, ARow]);
  end;
end;

un seul inconvénient est que cela répete le même numéro dans la ligne afin de pouvoir la colorier entièrement..
mais c'est plus rapide.

cantador
0
Frank_klein Messages postés 34 Date d'inscription samedi 26 mars 2005 Statut Membre Dernière intervention 8 février 2022
6 août 2008 à 00:55
bonjour, moi j'ai pas de message d'erreur, peut être ça dépend du code du programme dans lequel on l'intègre. L'inconvénient dont tu parle est de taille, car s'il me mettrait le même chiffre sur toute la ligne, dasn mon cas cela ne m'est pas utile du tout, j'ai autant des valeur différentes que de lignes et de colonnes sur ma stringgrid,  les erreurs je les vire avec try ---except, ça, pourvu qu'il me fasse tout le reste...le code d'Oniria je le troue bien fait, il est ergonomique ne bouffe pas des ressources, j'avais commencé à désespérer, donc ça ma été d'un grand secours, merci à tous
@+
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
6 août 2008 à 08:47
Attention, les messages d'erreur ne se produisent qu'en exécutant avec delphi...
en effet lorsqu'une cellule est vide strtoint(cells[Acol,Arow]) déclenche une erreur..
on peut effectivement étouffer certaines erreurs, mais en prenant des précautions, mais si on peut les comprendre et les traiter, c'est encore mieux.

Quand, à la répétition des chiffres, je te confirme que la ligne :
canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + 2, Cells[ACol, ARow]);
répéte, x fois le même chiffre sur toute la ligne trouvé dans la colonne 4..

Et c'est la raison pour laquelle, toute la ligne se colorise..

c'est une solution comme une autre à condition que cette répétition ne gène pas.

A toi de voir.

cantador
0
Oniria Messages postés 292 Date d'inscription dimanche 14 mars 2004 Statut Membre Dernière intervention 18 décembre 2014 3
6 août 2008 à 10:11
En effet, le try .. except.. end; va étouffer l'erreur (c'est brutal mais efficace). J'ai fait cela car je suis parti sur le principe que la case vide n'est pas une sécurité suffisante. En effet, si dans la case, il y a un simple texte ou une valeur réelle, mon code ne plante pas le programme.
Surtout pour une colorisation de case, je trouve un plantage vraiment dommage.

Sinon, désolé pour le ACol:=4, c'est une erreur de copier-coller. En effet, il faut supprimer cette ligne.

A bientot

Oniria
0
PhilLu Messages postés 251 Date d'inscription lundi 9 novembre 2009 Statut Membre Dernière intervention 11 mai 2021
19 nov. 2013 à 23:55
Salut,
mon problème est que avec ce code:

With SGSample As TStringGrid Do
With Canvas Do
Begin
if ((Cells[4,i]='POS') AND (Cells[2,i]='NEG')) OR ((Cells[4,i]='NEG') AND (Cells[2,i]='POS')) then
begin
Rect := CellRect(4, i);
Brush.Color := clRed;
Font.Color := clWhite;
FillRect(Rect);
TextRect(Rect, Rect.Left + 2, Rect.Top + 2, Cells[4, i]);

Rect := CellRect(2, i);
Brush.Color := clRed;
Font.Color := clWhite;
FillRect(Rect);
TextRect(Rect, Rect.Left + 2, Rect.Top + 2, Cells[2, i]);
end;
end;
les cellules se colorent en rouge comme prévu mais seulement une fraction de seconde???
J'aurais oublié quelque chose???

Merci pour votre aide!
0
Rejoignez-nous