Comment colorier une ligne de StringGrid quand la veluer d'une de ses cellules d [Résolu]

Frank_klein 34 Messages postés samedi 26 mars 2005Date d'inscription 8 avril 2011 Dernière intervention - 30 juil. 2008 à 15:10 - Dernière réponse : PhilLu 249 Messages postés lundi 9 novembre 2009Date d'inscription 6 mai 2018 Dernière intervention
- 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.


@+
Afficher la suite 

Votre réponse

18 réponses

Meilleure réponse
Oniria 297 Messages postés dimanche 14 mars 2004Date d'inscription 18 décembre 2014 Dernière intervention - 5 août 2008 à 11:40
3
Merci
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

Merci Oniria 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 101 internautes ce mois-ci

Commenter la réponse de Oniria
HAFTARIFOUAD 298 Messages postés mercredi 5 septembre 2007Date d'inscription 6 janvier 2011 Dernière intervention - 30 juil. 2008 à 19:18
0
Merci
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.
Commenter la réponse de HAFTARIFOUAD
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 30 juil. 2008 à 19:48
0
Merci
bonsoir,

Fouad, c'est un stringgrid...

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 - 30 juil. 2008 à 21:09
0
Merci
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
Commenter la réponse de cs_cantador
Frank_klein 34 Messages postés samedi 26 mars 2005Date d'inscription 8 avril 2011 Dernière intervention - 30 juil. 2008 à 22:09
0
Merci
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
Commenter la réponse de Frank_klein
Frank_klein 34 Messages postés samedi 26 mars 2005Date d'inscription 8 avril 2011 Dernière intervention - 31 juil. 2008 à 12:05
0
Merci
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


 
Commenter la réponse de Frank_klein
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 31 juil. 2008 à 17:32
0
Merci
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
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 - 31 juil. 2008 à 21:14
0
Merci
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
Commenter la réponse de cs_cantador
Frank_klein 34 Messages postés samedi 26 mars 2005Date d'inscription 8 avril 2011 Dernière intervention - 31 juil. 2008 à 21:41
0
Merci
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.
Commenter la réponse de Frank_klein
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 31 juil. 2008 à 22:05
0
Merci
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
Commenter la réponse de cs_cantador
Frank_klein 34 Messages postés samedi 26 mars 2005Date d'inscription 8 avril 2011 Dernière intervention - 1 août 2008 à 11:57
0
Merci
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. @ +
Commenter la réponse de Frank_klein
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 1 août 2008 à 14:31
0
Merci
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
Commenter la réponse de cs_cantador
Frank_klein 34 Messages postés samedi 26 mars 2005Date d'inscription 8 avril 2011 Dernière intervention - 5 août 2008 à 13:20
0
Merci
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  
@+
Commenter la réponse de Frank_klein
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 5 août 2008 à 19:14
0
Merci
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
Commenter la réponse de cs_cantador
Frank_klein 34 Messages postés samedi 26 mars 2005Date d'inscription 8 avril 2011 Dernière intervention - 6 août 2008 à 00:55
0
Merci
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
@+
Commenter la réponse de Frank_klein
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 6 août 2008 à 08:47
0
Merci
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
Commenter la réponse de cs_cantador
Oniria 297 Messages postés dimanche 14 mars 2004Date d'inscription 18 décembre 2014 Dernière intervention - 6 août 2008 à 10:11
0
Merci
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
Commenter la réponse de Oniria
PhilLu 249 Messages postés lundi 9 novembre 2009Date d'inscription 6 mai 2018 Dernière intervention - 19 nov. 2013 à 23:55
0
Merci
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!
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.