Rafraichissement DBGrid [Résolu]

cs_Juju1988 70 Messages postés jeudi 8 janvier 2009Date d'inscription 21 juin 2011 Dernière intervention - 20 juin 2011 à 14:10 - Dernière réponse : cs_MAURICIO 2233 Messages postés mardi 10 décembre 2002Date d'inscription 15 décembre 2014 Dernière intervention
- 22 juin 2011 à 10:12
Bonjour à tous,

J'ai un petit soucis j'ai un DBGrid qui m'affiche des scanners via un OracleDataSet et qui me dessine des cases à cocher cochées ou non via :

// Procédure permettant de dessiner dans les colonnes d'un DBgrid
procedure TMainForm.DBGridScanDrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
begin
  AfficheCaseSav(Rect,Column, DBGridScan, DmImages.imgCheck, DataCol, state);
end;


Voici la procédure :

// Procédure permettant de dessiner les cases à cocher dans la colonne SAV du DBGridScan
procedure AfficheCaseSav(const Rectangle: TRect; maCol : TColumn; monDB : TDBGrid; monJeuDImages : TImageList; colData : Integer; monEtat : TGridDrawState);
begin
if sameText(maCol.FieldName, 'SAV') then
  begin
    { On efface la cellule }
    monDB.Canvas.FillRect(Rectangle);
    { Cochée ou Pas ?}
    monJeuDImages.Draw(monDB.Canvas,
      Rectangle.Left + ((Rectangle.Right - Rectangle.Left - monJeuDImages.Width) div 2),
      Rectangle.Top,
      Ord(monDB.Fields[3].AsString = '0')
    );
  end
  { si column ne correspond pas à une case à cocher, }
  { on ne s'occupe pas du dessin de la cellule, on }
  { transmet donc à DefaultDrawColumnCell }
  else
  begin
    monDB.DefaultDrawColumnCell(Rectangle, colData, maCol, monEtat);
  end;

end;


Cependant j'ai une zone de saisie qui me permet de faire des recherches de scanners cependant quand on commence à écrire cela me dessine toutes mes cases cochées alors qu'elles ne devraient pas l'être... j'ai pourtant mis un refresh je ne comprend pas...

// Permet de faire une recherche de scan
procedure TMainForm.zsRechercheScanChange(Sender: TObject);
begin
  MainForm.OracleDataSetGestionScan.Refresh;
  
  OracleDataSetGestionScan.Close;
  OracleDataSetGestionScan.SQL.Clear;
  OracleDataSetGestionScan.SQL.Add('SELECT * FROM adresseip WHERE nomscan LIKE ''%' + uppercase(zsRechercheScan.Text) +'%''');
  DataSourceGestionScan.DataSet := OracleDataSetGestionScan;
  DBGridScan.DataSource := DataSourceGestionScan;
  OracleDataSetGestionScan.Open;

  MainForm.OracleDataSetGestionScan.Refresh;

end;


Je ne comprend pas...

Merci d'avance pour votre aide
Afficher la suite 

16 réponses

Répondre au sujet
cs_Juju1988 70 Messages postés jeudi 8 janvier 2009Date d'inscription 21 juin 2011 Dernière intervention - 21 juin 2011 à 14:16
+3
Utile
J'ai eu une solution qui fonctionne sur un autre forum il faut mettre :

  monJeuDImages.Draw(monDB.Canvas,
      Rectangle.Left + ((Rectangle.Right - Rectangle.Left - monJeuDImages.Width) div 2),
      Rectangle.Top,
      Ord(maCol.Field.AsString = '0')    );


Merci de votre aide !!!
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de cs_Juju1988
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 20 juin 2011 à 15:46
0
Utile
Bonjour,

tente d'encapsuler ta recherche par :

try
"Objet".disablecontrols;

finally
"Objet".Enablecontrols;
end;

et supprime les refresh qui ne servent ici à rien..

cantador
Commenter la réponse de cs_cantador
cs_Juju1988 70 Messages postés jeudi 8 janvier 2009Date d'inscription 21 juin 2011 Dernière intervention - 20 juin 2011 à 16:02
0
Utile
ça me supprime carrément tout dans mon DBGrid (et dans mon DBGrid seulement...)

// Permet de faire une recherche de scan
procedure TMainForm.zsRechercheScanChange(Sender: TObject);
begin
  //MainForm.OracleDataSetGestionScan.Refresh;

try

    OracleDataSetGestionScan.DisableControls;

  OracleDataSetGestionScan.Close;
  OracleDataSetGestionScan.SQL.Clear;
  OracleDataSetGestionScan.SQL.Add('SELECT * FROM adresseip WHERE nomscan LIKE ''%' + uppercase(zsRechercheScan.Text) +'%''');
  DataSourceGestionScan.DataSet := OracleDataSetGestionScan;
  DBGridScan.DataSource := DataSourceGestionScan;
  OracleDataSetGestionScan.Open;


  finally

    OracleDataSetGestionScan.EnableControls;


end;
Commenter la réponse de cs_Juju1988
beckerich 309 Messages postés jeudi 29 septembre 2005Date d'inscription 17 septembre 2013 Dernière intervention - 20 juin 2011 à 20:26
0
Utile
Bonjour,

juste une petite correction, qui d'ailleurs dans ce contexte ne change rien :

objet.DisableControls;
try
  // traitement
finally
  objet.EnableControls;
end;


Il faut sortir le DisableControls du bloc
try, car si cette ligne échoue, pas besoin du
finally. C'est important dans le cas d'une
allocation de mémoire, par exemple.

toto := TObject.Create;
try
(********************************************
si toto := TObject.Create est fait ici et que
 cela se passe mal, le bloc finally sera 
exécuté, et on tentera de libérer un objet 
non alloué, ce qui provoquera un joli 
RunTimeError ou qque chose dans le genre ;-))
********************************************)
  Caption := toto.ClassName;
finally
  toto.Free;
end


Luc.
Commenter la réponse de beckerich
cs_Juju1988 70 Messages postés jeudi 8 janvier 2009Date d'inscription 21 juin 2011 Dernière intervention - 21 juin 2011 à 08:13
0
Utile
Oui c'est ce que j'ai fait après :

procedure TMainForm.zsRechercheScanChange(Sender: TObject);
begin
    OracleDataSetGestionScan.DisableControls;
  try

    OracleDataSetGestionScan.Close;
    OracleDataSetGestionScan.SQL.Clear;
    OracleDataSetGestionScan.SQL.Add('SELECT * FROM adresseip WHERE nomscan LIKE ''%' + uppercase(zsRechercheScan.Text) +'%''');
    DataSourceGestionScan.DataSet := OracleDataSetGestionScan;
    DBGridScan.DataSource := DataSourceGestionScan;
    OracleDataSetGestionScan.Open;
  finally
    OracleDataSetGestionScan.EnableControls;
  end;
end;


Mais j'ai toujours mon problème de rafraichissement... Là ça me vide carrément mon DBGrid...

SVP aidez moi je ne sais plus quoi faire...
Commenter la réponse de cs_Juju1988
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 21 juin 2011 à 09:24
0
Utile
le DisableControls et le EnableControls permettent de désactiver l'affichage d'un objet pendant un traitement.
Cela ne concerne pas la libération d'un objet..

mais mis à part cette précision, cela ne règle pas ton problème..
et je n'ai pas delphi à côté de moi pour tester.

autre chose le OnDrawColumnCell est une procédure évènementielle qui s'active en permanence..et déclencher une recherche pendant l'exécution de cette dernière n'est pas simple..

On pourrait toutefois désactiver l'évènement pendant la recherche,
en le déclarant à nil et le remettre ensuite mais je ne le sens pas du tout.

il doit y avoir une autre solution..

Le mieux serait de décrire exactement ce que tu souhaites réaliser
et là je pense qu'une idée va germer.


cantador
Commenter la réponse de cs_cantador
cs_Juju1988 70 Messages postés jeudi 8 janvier 2009Date d'inscription 21 juin 2011 Dernière intervention - 21 juin 2011 à 10:19
0
Utile
En fait j'ai une table qui stocke des scanners :
- AdresseIP
- Nom
-...
Et elle stocke aussi s'ils sont en SAV (réparation) si 0 pas en SAV si 1 SAV.
Donc ces scans je les affiche dans un DBGrid et pour la colonne SAV si le scan est en SAV ça m'affiche une case cochée si pas en SAV case non cochée d'où le code :

// Procédure permettant de dessiner les cases à cocher dans la colonne SAV du DBGridScan
procedure AfficheCaseSav(const Rectangle: TRect; maCol : TColumn; monDB : TDBGrid; monJeuDImages : TImageList; colData : Integer; monEtat : TGridDrawState);
begin
// On ne prend en compte que la colonne SAV
if sameText(maCol.FieldName, 'SAV') then
  begin
    { On efface la cellule }
    monDB.Canvas.FillRect(Rectangle);
    { Cochée ou Pas ?}
    monJeuDImages.Draw(monDB.Canvas,
      Rectangle.Left + ((Rectangle.Right - Rectangle.Left - monJeuDImages.Width) div 2),
      Rectangle.Top,
      Ord(monDB.Fields[3].AsString = '0')
    );
  end
  { si column ne correspond pas à une case à cocher, }
  { on ne s'occupe pas du dessin de la cellule, on }
  { transmet donc à DefaultDrawColumnCell }
  else
  begin
    monDB.DefaultDrawColumnCell(Rectangle, colData, maCol, monEtat);
  end;

end;


appelée par :

// Procédure permettant de dessiner dans les colonnes d'un DBgrid
procedure TMainForm.DBGridScanDrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
begin
  AfficheCaseSav(Rect,Column, DBGridScan, DmImages.imgCheck, DataCol, state);
end;


C'est une gestion des scans. Donc par exemple après mon ajout d'un scan je fais un refresh après ma requête pour bien que ce soit pris en compte pareil après un ajout SAV exemple :


// Ajout ou Modif d'un SAV pour un scan donné
procedure TFrmAjoutSAV.btnOkClick(Sender: TObject);
var
  nomDuScan : String;
  nextval : integer;

begin
nomDuScan := '';
nomDuScan := lblNomScan.Caption;

// Ajout d'un SAV
if typeModif = 'Ajout' then
  begin
  oqAjoutSav.Close;
  oqAjoutSav.SQL.Clear;                                                                                             // SEQ_NUMSUIVI permet de récupérer le numéro de suivi suivant relatif à la table SUIVISAV
                                                                                                                   // mais possible grâce à une séquence Oracle SEQ_NUMSUIVI qui s'auto-incrémente
  oqAjoutSav.SQL.Add('INSERT INTO suivisav (numsuivi, numrma, datedepart, dateretour, nomscan, commentaire) VALUES (SEQ_NUMSUIVI.NEXTVAL, :numerorma, :datededepart, :datederetour, :lenomscan, :com)');
  oqAjoutSav.DeclareAndSet('numerorma', otString, uppercase(zsNumRma.Text));
  oqAjoutSav.DeclareAndSet('datededepart', otString, zsDateDep.Text);
  oqAjoutSav.DeclareAndSet('datederetour', otString, zsDateRetour.Text);
  oqAjoutSav.DeclareAndSet('lenomscan', otString, nomDuScan);
  oqAjoutSav.DeclareAndSet('com', otString, zsCommentaires.Text);
  oqAjoutSav.Execute;
  oqAjoutSav.Session.Commit;

  oqMajScan.Close;
  oqMajScan.SQL.Clear;
  oqMajScan.SQL.Add('UPDATE adresseip SET sav 1 WHERE nomscan :nomdescan');
  oqMajScan.DeclareAndSet('nomdescan', otString, nomDuScan);
  oqMajScan.Execute;
  oqMajScan.Session.Commit;

  end
  //Modif d'un SAV, saisie d'une date de retour...
else if typeModif = 'Modif' then
  begin
  oqModifSav.Close;
  oqModifSav.SQL.Clear;
  oqModifSav.SQL.Add('UPDATE suivisav SET numrma :nvrma, datedepart :nvdepart, dateretour = : nvretour, commentaire = :nvcommentaire WHERE nomscan = :nvscan');
  oqModifSav.DeclareAndSet('nvrma', otString, uppercase(zsNumRma.Text));
  oqModifSav.DeclareAndSet('nvdepart', otString, zsDateDep.Text);
  oqModifSav.DeclareAndSet('nvretour', otString, zsDateRetour.Text);
  oqModifSav.DeclareAndSet('nvcommentaire', otString, zsCommentaires.Text);
  oqModifSav.DeclareAndSet('nvscan', otString, nomDuScan);
  oqModifSav.Execute;
  oqModifSav.Session.Commit;

    if (zsDateRetour.Text <> '  /  /    ') and (Trim(zsDateRetour.Text) <> '') then
      begin
      oqMajScan.Close;
      oqMajScan.SQL.Clear;
      oqMajScan.SQL.Add('UPDATE adresseip SET sav 0 WHERE nomscan :nomdescan');
      oqMajScan.DeclareAndSet('nomdescan', otString, nomDuScan);
      oqMajScan.Execute;
      oqMajScan.Session.Commit;
      end;
  end;


  zsNumRma.Text := '';
  zsCommentaires.Text := '';
  zsDateDep.Text := '  /  /    ';
  zsDateRetour.Text := '  /  /    ';

  FrmHistoSav.OracleDataSetHisto.Close;
  FrmHistoSav.OracleDataSetHisto.SQL.Clear;
  FrmHistoSav.OracleDataSetHisto.SQL.Text :'SELECT numsuivi, nomscan, numrma, datedepart, dateretour, commentaire FROM suivisav WHERE nomscan :nomduscan ORDER BY dateretour';
  FrmHistoSav.OracleDataSetHisto.DeclareAndSet('nomduscan', otString, nomDuScan);
  FrmHistoSav.DataSourceHisto.DataSet := FrmHistoSav.OracleDataSetHisto;
  FrmHistoSav.DBGridHisto.DataSource := FrmHistoSav.DataSourceHisto;
  FrmHistoSav.OracleDataSetHisto.Open;

  // On rafraichit l'affichage du DBGrid en rafraichissant le DataSet
  MainForm.OracleDataSetGestionScan.Refresh;
  // Comme ouverture du formulaire en modal on le ferme en modal également de cette façon
  ModalResult := mrOk;

end;




Cependant pour ma zone de saisie qui me permet de faire une recherche sur le nom du scan et d'afficher le résultat en temps réel cela ne fonctionne pas si je commence à taper un nom cela me coche toutes les cases et pareil si après j'efface le texte dans ma zone de recherche. Le refresh ici ne fonctionne pas :

// Permet de faire une recherche de scan dans le DBGrid
procedure TMainForm.zsRechercheScanChange(Sender: TObject);
begin
    OracleDataSetGestionScan.DisableControls;
  try

    OracleDataSetGestionScan.Close;
    OracleDataSetGestionScan.SQL.Clear;
    OracleDataSetGestionScan.SQL.Add('SELECT * FROM adresseip WHERE nomscan LIKE ''%' + uppercase(zsRechercheScan.Text) +'%''');
    DataSourceGestionScan.DataSet := OracleDataSetGestionScan;
    DBGridScan.DataSource := DataSourceGestionScan;
    OracleDataSetGestionScan.Open;
  finally
    OracleDataSetGestionScan.EnableControls;
  end;
end;


Disable et EnableControls me supprime complètement les enregistrements du tableau (d'un point de vue affichage bien sûr).

Voilà je pense que j'ai tout dit ... Si tu as des questions n'hésite pas...
Commenter la réponse de cs_Juju1988
beckerich 309 Messages postés jeudi 29 septembre 2005Date d'inscription 17 septembre 2013 Dernière intervention - 21 juin 2011 à 13:22
0
Utile
bonjour,

@cantador,

merci, je sais bien que Enable/DisableControls n'ont rien à voir avec la libération d'une ressource allouée,
mais le try finally oui...
C'était simplement une petite précision sur l'utilisation d'un tel bloc.

Pour en revenir au problème,

nomDuScan := Uppercase(lblNomScan.Caption);

change-t-il quelque chose ?

Si j'ai bien compris, sans le bloc Enable/Disable, le dbgrid affiche les données, pas comme il faut mais
il les affiche ?
Crées-tu les colonnes du dbgrid en design ou en runtime ? C'est peut-être aussi une piste à essayer.
J'essaye qque chose chez moi et je reviens.

Luc.
Commenter la réponse de beckerich
cs_Juju1988 70 Messages postés jeudi 8 janvier 2009Date d'inscription 21 juin 2011 Dernière intervention - 21 juin 2011 à 13:36
0
Utile
Uppercase ne change rien...
Oui il affiche les données. Mais me met pas le bon dessin de cases il me met des cases à cocher au lieu de cases vides.
Les colonnes du DBgrid sont crées dynamiquement par ma requête d'affichage...
Commenter la réponse de cs_Juju1988
beckerich 309 Messages postés jeudi 29 septembre 2005Date d'inscription 17 septembre 2013 Dernière intervention - 21 juin 2011 à 14:04
0
Utile
Re,

j'ai testé ce code chez moi sur Delphi 7 et base Informix, il fonctionne (table de 150000 records) :

procedure TFM_MAIN.SED_CAT1Change(Sender: TObject);
begin
  with IfxQuery1 do
  begin
    DisableControls;
    try
      Close;
      SQL.Clear;
      SQL.Add('select * from lal_ini where cleini like ''%' + SED_CAT1.Text + '%''');
      Open;
    finally
      EnableControls;
    end;
  end;
end;

procedure TFM_MAIN.AfficheCaseSav(const Rectangle: TRect; maCol: TColumn;
  monDB: TDBGrid; monJeuDImages: TImageList; colData: Integer;
  monEtat: TGridDrawState);
begin
  if monDB.Datasource.DataSet.FieldByName('VALPAR').AsString = '1' then
  begin
    { On efface la cellule }
    monDB.Canvas.FillRect(Rectangle);
    { Cochée ou Pas ?}
    monJeuDImages.Draw(monDB.Canvas,
      Rectangle.Left + ((Rectangle.Right - Rectangle.Left - monJeuDImages.Width) div 2),
      Rectangle.Top, 2);
  end
  { si column ne correspond pas à une case à cocher, }
  { on ne s'occupe pas du dessin de la cellule, on }
  { transmet donc à DefaultDrawColumnCell }
  else
  begin
    monDB.DefaultDrawColumnCell(Rectangle, colData, maCol, monEtat);
  end;
end;

procedure TFM_MAIN.DBGrid1DrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
begin
  AfficheCaseSav(Rect, Column, DBGrid1, ImageList1, 2, State);  
end;



Je n'ai pas d'idée pour le moment. Désolé,
Luc.
Commenter la réponse de beckerich
beckerich 309 Messages postés jeudi 29 septembre 2005Date d'inscription 17 septembre 2013 Dernière intervention - 21 juin 2011 à 14:07
0
Utile
Ord(monDB.Fields[3].AsString = '0');


si '0' donne True donc ImageIndex=1
si <> '0' donne False donc ImageIndex=0

les images du ImageList sont à la bonne place ?

Luc.
Commenter la réponse de beckerich
cs_Juju1988 70 Messages postés jeudi 8 janvier 2009Date d'inscription 21 juin 2011 Dernière intervention - 21 juin 2011 à 14:17
0
Utile
Oui sinon les images dans bien dans l'imageList
Commenter la réponse de cs_Juju1988
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 21 juin 2011 à 14:17
0
Utile
Bonjour,

@beckerich :
toto := TObject.Create;
tu raisonnes comme si un objet était en création..
mais ici, il n'y en a pas et dans ce cas cette écriture ne pose pas de souci.
Effectivement, s'il y en avait un, ce serait une erreur d'écriture..
il faut simplement adapter..

@Juju1988 :
si je commence à taper un nom cela me coche toutes les cases

Oui, c'est normal..
toutes les procédures se déclenchent en même temps sans aucun contrôle..

ça veut dire que la méthode n'est pas correcte et qu'il faut revoir le concept..

il ne faut pas hésiter à tout refaire dans un autre environnement :
ex : changer de système d'affichage :
StringGrid, drawGrid, ListView etc..
jouer aussi sur la couleur..

le TDbgrid est rapide et léger, mais pauvre en affichage..
(avec un TcxGrid, la solution serait vite trouvée..car tout pourrait être réalisé en dynamique)

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 - 21 juin 2011 à 14:21
0
Utile
@Juju1988 :

posts croisés..

content que tu es trouvé quelque chose


cantador
Commenter la réponse de cs_cantador
cs_Juju1988 70 Messages postés jeudi 8 janvier 2009Date d'inscription 21 juin 2011 Dernière intervention - 21 juin 2011 à 14:24
0
Utile
Vouiiiii moi aussi merci de ton aide :)
Commenter la réponse de cs_Juju1988
cs_MAURICIO 2233 Messages postés mardi 10 décembre 2002Date d'inscription 15 décembre 2014 Dernière intervention - 22 juin 2011 à 10:12
0
Utile
Solution: tcyDBGrid ou tcyDBAdvGrid de mon pack de compos qui gèrent déjà le checkbox ici, télécharge aussi la démo :
Composants Cindy pour Delphi

A+
Commenter la réponse de cs_MAURICIO

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.