Frank_klein
Messages postés34Date d'inscriptionsamedi 26 mars 2005StatutMembreDernière intervention 8 février 2022
-
30 juil. 2008 à 15:10
PhilLu
Messages postés251Date d'inscriptionlundi 9 novembre 2009StatutMembreDernière intervention11 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.
Oniria
Messages postés292Date d'inscriptiondimanche 14 mars 2004StatutMembreDernière intervention18 décembre 20143 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]);
HAFTARIFOUAD
Messages postés256Date d'inscriptionmercredi 5 septembre 2007StatutMembreDerniè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;
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
Vous n’avez pas trouvé la réponse que vous recherchez ?
Frank_klein
Messages postés34Date d'inscriptionsamedi 26 mars 2005StatutMembreDerniè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.
Frank_klein
Messages postés34Date d'inscriptionsamedi 26 mars 2005StatutMembreDerniè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.
cs_cantador
Messages postés4720Date d'inscriptiondimanche 26 février 2006StatutModérateurDernière intervention31 juillet 202113 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)
cs_cantador
Messages postés4720Date d'inscriptiondimanche 26 février 2006StatutModérateurDernière intervention31 juillet 202113 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..
Frank_klein
Messages postés34Date d'inscriptionsamedi 26 mars 2005StatutMembreDerniè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.
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;
Frank_klein
Messages postés34Date d'inscriptionsamedi 26 mars 2005StatutMembreDerniè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. @ +
cs_cantador
Messages postés4720Date d'inscriptiondimanche 26 février 2006StatutModérateurDernière intervention31 juillet 202113 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;
Frank_klein
Messages postés34Date d'inscriptionsamedi 26 mars 2005StatutMembreDerniè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
cs_cantador
Messages postés4720Date d'inscriptiondimanche 26 février 2006StatutModérateurDernière intervention31 juillet 202113 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.
Frank_klein
Messages postés34Date d'inscriptionsamedi 26 mars 2005StatutMembreDerniè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
@+
cs_cantador
Messages postés4720Date d'inscriptiondimanche 26 février 2006StatutModérateurDernière intervention31 juillet 202113 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.
Oniria
Messages postés292Date d'inscriptiondimanche 14 mars 2004StatutMembreDernière intervention18 décembre 20143 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.
PhilLu
Messages postés251Date d'inscriptionlundi 9 novembre 2009StatutMembreDernière intervention11 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]);