DBGrid et alignement

Signaler
Messages postés
129
Date d'inscription
mercredi 4 février 2004
Statut
Membre
Dernière intervention
25 juillet 2012
-
informatixo
Messages postés
129
Date d'inscription
mercredi 4 février 2004
Statut
Membre
Dernière intervention
25 juillet 2012
-
Bonjour,

Est-il possible avec une DBGrid de gérer un alignement ligne par ligne ?

En effet, j'ai un champ désignation et je voudrais pouvoir paramètrer chaque ligne différement.

Sinon, lors de mes recherches j'ai vu qu'il était possible de manipuler les données via un DBMemo pour les champs blob memo mais serait-il possible d'intégrer un DBRichEdit à un DBGrid comme un CheckBox comme je l'ai vu sur d'autres sources ?

C'est très frustrant de voir des logiciels de comptabilité où l'on peut formatter le texte comme dans word à l'intérieur de chaque cellule et de ne pas pouoir y arriver avec un DBGrid.

Pourtant j'ai cherché mais je n'ai pas trouver comment faire avec un RichEdit. Par exemple il y a ce lien qui est assez intéressant mais je n'ai pas pu y trouver mon bonheur.

Pourtant certaines personnes comme Delphiprog, NoNo40, Mauricio (pour ne citer qu'eux mais il y en a d'autres) font des codes très avancés sur les DBGrid.

Et je partage leur avis sur le fait que c'est un composant très puissant.

Je ne demande pas que l'on me fasse le travail (il est plus intéressant d'y arriver par soi-même) mais si quelqu'un avait quelques pistes sur les fonctions API à utiliser (s'il y a lieu) ou sur les évènements à utiliser pour pouvoir arriver à un résultat, vous m'enleveriez une bonne épine du pied.

Je voudrais arriver à un résultat similaire à ce lien mais avec DBRichEdit. Il y aussi ce lien pour des astuces assez avancées sur les DBGrid.

Je précise que je me sers d'un DBGrid avec des composants ADO (situés dans un module de donées) sur une base de données Access 2003.

Le champ où je voudrais intégrer mon DBRichEdit est un champ persistant lié à un blob Memo Field intitulé "des".

Ma DBGrid est en mode édition et j'ai activé la propriété "AlwaysShowEditor".

Merci d'avance pour votre participation et votre aide.

8 réponses

Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
26
Bonjour Informatixo,

Avec Delphi, qu'est-ce qui ne serait pas possible ?
Sans plus tarder, voici le code que je te propose :

procedure TForm1.FormCreate(Sender: TObject);
begin
  {Un contrôle TDbRichEdit est placé n'importe où sur la fiche.
  Il ne sera visible que quand on le lui demandera}
  DBRichEdit1.Visible :=  False;
 end ;

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  DrawRect: TRect;
  btnText: PAnsiChar;
begin
  {Si le DbGrid détient le focus}
  if gdFocused in State then
  begin
    {Si le champ de la colonne  est le même que celui relié au TDbRichEdit}
    if Column.Field  = DbRichEdit1.Field then
      with DBGrid1 do
      begin
        {On positionne le TDbRichEdit avec le coin supérieur gauche
        aligné sur le rectangle à dessiner}
        DbRichEdit1.Left :=  Rect.Left + 2;
        DbRichedit1.Top := Rect.Top + 2;
        {Pour que le TDbRichEdit apparaisse au dessus du DBGrid,
        il faut affecter sa propriété parent à celle du Grid}
        DbRichEdit1.Parent := DbGrid1;
        {Maintenant, on peut afficher le contrôle de saisie}
        DbRichedit1.Visible := True;
        DbRichEdit1.SetFocus;
      end
  end
  else
     if  Column.Field  = DbRichEdit1.Field then
    begin
      {Quand la colonne n'a pas le focus, on dessine un
      bouton}
      DrawRect :=  Rect;
      InflateRect(DrawRect, -1, -1);
      DBGrid1.Canvas.FillRect(Rect);
      {Dessinbe un bouton}
      DrawFrameControl(DBGrid1.Canvas.Handle, DrawRect, DFC_BUTTON, DFCS_BUTTONPUSH);
      {Mettre un libellé sur le bouton}
      btnText := StrNew('cliquer ici');
      DrawText(DbGrid1.Canvas.Handle, btnText, StrLen(btnText), DrawRect, DT_CENTER  or  DT_VCENTER or DT_WORDBREAK);
      StrDispose(btnText);
    end;
end;

procedure TForm1.DBGrid1ColExit(Sender: TObject);
begin
  {Masquer le contrôle TDbRichEdit quand on quitte la colonne}
  if DbGrid1.SelectedField.FieldName  = DbRichEdit1.DataField then
    DbRichedit1.Visible :=  False;
 end ;

procedure TForm1.DBRichEdit1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  {La touche ESC permet de rendre invisible le contrôle TDbRichEdit}
  if Key  = VK_ESCAPE then
    DbRichEdit1.Visible :=  False;
 end ;

Je dois préciser que je me suis largement inspiré de la page web CheckBox inside a DBGrid 
mais qu'il a fallu malgré tout procéder à quelques remaniements. En effet, le code était trop orienté pour afficher une case à cocher. Tu me rétorqueras surement que le mien est très orienté TDbRichEdit... et tu auras raison.

Merci de me dire ce que tu en penses.

May Delphi be with you !


<hr color ="#008000" />
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
Messages postés
129
Date d'inscription
mercredi 4 février 2004
Statut
Membre
Dernière intervention
25 juillet 2012
1
Bonjour Delphiprog,

"Merci de me dire ce que tu en penses" > j'en pense que c'est tout simplement génial ! ! !
Ton travail est totalement remarquable (j'aimerais que ce soit aussi facile pour moi !).

Je me suis mal exprimé en posant ma question sur ce que je voulais. Dans ton super exemple, quand on clique sur le bouton "Cliquez ici", le DBRichEdit apparaît comme par enchantement à la bonne place et tout fonctionne à merveille.

En fait, ce que je voudrais, c'est des DBRichEdit partout sur la grille à la place des boutons "Cliquez ici". Sur chaque ligne à la place de (MEMO) j'ai un bouton avec "Cliquez ici" comme légende et moi je voudrais un DBRichEdit à la place avec le texte. Ainsi, j'évite la limitation du fameux "(MEMO)".

Je te rassure (ou pas !), j'ai quand même cherché de mon  côté (sur le même lien dont nous parlons tous les deux) et en fait je bloque sur l'utilisation du "DrawFrameControl".

En effet, mon idée était de dessiner un DBRichEdit avec "DrawFrameControl".

Mais en recherchant sur le site de microsoft la fonction "DrawFrameControl" de l'API Windows à cette adresse, pour les interessés (vaut le détour) , je me demande si c'est possible !

Car ils mentionnent le fait que si "uType" possède "DFC_BUTTON" alors "uState" peut prendre comme valeur (bouton trois états, CheckBox, bouton poussoir, bouton radio, image pour bouton radio, masque pour bouton radio) mais nullement un autre composant tel DBRichEdit.

Sinon, mon autre réflexion, c'est d'afficher une image imitant le DBRichEdit avec le texte adéquat (situé dans mon Dataset) pour chaque ligne et d'afficher le composant réel lorsque je clique sur la ligne voulue.

Je ne sais pas quoi penser de mon analyse de ce problème (ça c'est un premier point !), ni comment y remédier (ça c'est le deuxième point et de loin le plus ennuyeux -> faut vite que j'ailles prendre des cours d'humour avec japee car c'est pas trop ça encore lol).

Non, plus sérieusement, ça fait un bon moment que je me casse la tête dessus mais je vais persévérer.

En tout cas, grâce à ton code Delphiprog je fais un pas de géant !

Merci beaucoup pour ton aide si appréciable.

Si d'autres personnes veulent venir s'arracher les neuronnes avec nous sur ce problème existenciel , ils sont les bienvenus.
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
26
Ah ben là, je suis déçu que ça ne corresponde pas à 100 % de tes attentes.
Nan, je plaisante...

En fait, ce que je voudrais, c'est des DBRichEdit partout sur la grille à la place des boutons "Cliquez ici". Sur chaque ligne à la place de (MEMO) j'ai un bouton avec "Cliquez ici" comme légende et moi je voudrais un DBRichEdit à la place avec le texte. Ainsi, j'évite la limitation du fameux "(MEMO)".
Dans ce cas là, ne serait-il pas plus sage d'utiliser un TDbCtrlGrid  et d'y mettre un TDbRichEdit sur chacun des panels ?

"Sinon, mon autre réflexion, c'est d'afficher une image imitant le DBRichEdit avec le texte adéquat (situé dans mon Dataset) pour chaque ligne et d'afficher le composant réel lorsque je clique sur la ligne voulue."
Je me suis posé la question sur ce que je devais faire sur ce point et je me suis dit que comme on n'afficherait jamais qu'une ligne (au plus deux) cela n'avait aucun intérêt et qu'il valait mieux afficher plus de contenu moyennant un clic sur la colonne. C'est un argument qui vaut ce qu'il vaut. Je suis prêt à le défendre...tant qu'il me reste encore quelques neurones .

May Delphi be with you !
<hr color="#008000" />
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
Messages postés
129
Date d'inscription
mercredi 4 février 2004
Statut
Membre
Dernière intervention
25 juillet 2012
1
Bonjour Delphiprog,

Dans ce cas là, ne serait-il pas plus sage d'utiliser un TDbCtrlGrid  et d'y mettre un TDbRichEdit sur chacun des panels ? -> Je ne connaissais pas ce composant mais pourquoi pas. Peut-on le placer sur le DBGrid ou doit-il obligatoirement être placé à côté du DBGrid ?

... je me suis dit que comme on n'afficherait jamais qu'une ligne (au plus deux) ... -> Je ne comprend pas trop ce que tu veux dire ? Tu veux dire qu'il n'y aura qu'une seule ou deux lignes d'afficher dans le DBGrid ou qu'une seule sera modifié à la fois ? (décidement mes neurones sont létargiques )

En fait, ma DBGrid sert de détail de facture. J'ai une colonne numéro de ligne (fixe "grisée"), désignation (celle en blob dont on parle), quantité, prix de vente HT, montant HT (champ calculé).

Cette grille est mode édition (avec AlwaysShowEditor à True) et je recherche à faire en sorte que l'utilisateur puisse se déplacer d'une cellule à l'autre en tabulant et évidement le champ qui doit subir le plus de changements (formatage de police, alignement, etc.) et celui qui en permet le moins, à savoir la désignation.

Le formatage avec un DBRichEdit n'est pas un problème, ce qui n'est pas évident pour moi c'est de mettre en place mon DBRichEdit à la bonne ligne quand je rentre dans la cellule désignation (ce qui est le cas maintenant grâce à ton exemple précédent) et de faire en sorte que lorsque que je sors de cette cellule désignation, l'utilisateur soit toujours capable de voir ce que contient chaque cellule de désignation pour l'ensemble de la grille. Et là c'est pas gagné !

Je te remercie de m'aider à nouveau Delphiprog.

The Delphi force isn't with me at this time ! But I want to always believe in it
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
26
Bonjour Informatixo,

1/- L'intérêt du composant TDbCtrlGrid est de pouvoir disposer n'importe quel contrôle dessus. Il semble donc répondre à ta problèmatique, faute de mieux.

2/- La hauteur des lignes d'un TDbGrid est un peu limitée et il serait difficile d'en augmenter la taille sans rendre difficile la lecture des autres champs.


Je pense que, pour conserver une bonne lisibilité du détail de la facture, il serait plus simple de mettre le contrôle TDbRichEdit en dehors de la grille TDbGrid. Cela dit, rien ne t'empêche non plus d'agrandir ton TDbRichEdit ou de rendre sa taille variable à l'exécution.
Après, tout est question de choix et cela est de ton ressort.

May Delphi be with you and continue to believe in it !


<hr color="#008000" />
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
Messages postés
129
Date d'inscription
mercredi 4 février 2004
Statut
Membre
Dernière intervention
25 juillet 2012
1
Re Delphiprog,

Merci beaucoup pour tous ces conseils et ne t'inquiètes pas pour Delphi depuis que j'y ai goûté je ne reviendrais pas sur VB (hormis si on me le demande au boulot).

Je vais continuer à croire très fort en Delphi et je serais Delphiphile jusqu'à mon dernier souffle .

Je vais tester plusieurs choses et je reviendrais expliquer la solution que j'ai choisie et qui me paraît la plus adaptée dans mon cas de figure.

J'y vois plus clair et je t'en remercie.

A plus, pour de nouvelles aventures delphiennes !
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
26
<hr color="#008000" />
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
Messages postés
129
Date d'inscription
mercredi 4 février 2004
Statut
Membre
Dernière intervention
25 juillet 2012
1
Bonjour Delphiprog,

Du laisser-aller et pourquoi donc ?

Voici ce que j'ai retenue comme solution (elle n'est pas optimale certes mais bon elle a le mérite de fonctionner tout comme la tienne).

J'ai crée une autre form ou j'ai placé un panel avec des SpeedButton et un DBRichEdit. Puis j'ai enlevé la barre de titre de la fenêtre.

En fait, le panel et les boutons me permettent de formatter le texte.

Puis sur le ColEnter de la fameuse colonne "Désignation", je fais apparaître ma form décrite plus haut en prenant soin de l'aligner en haut et à gauche. Ainsi, dès que je cliques sur une ligne et sur cette colonne, la désignation est immédiatement éditée dans ma nouvelle form. Puis sur le ColExit je cache la form.

Ensuite, je me suis aidé d'une source pour les mémos (désolé je ne sais plus où mais il y en a beaucoup) qui me permet de recopier le texte du blob memo field dans la DBGrid à la place de l'inscription "(MEMO)".

Ainsi, dès que je suis sur la colonne "Désignation" mon contenu s'édite dans la form que j'ai créé spécialement, pour la ligne sélectionnée et dans le reste de cette colonne chaque champ possède son texte ou une partie si le contenu est trop grand.

Et si je ne suis pas sur la colonne "Désignation" et bien chaque cellule affiche quand même le contenu de son champ respectif.

Ce n'est pas tout à fait ce que je voulais mais c'est un bon compromis entre fonctionalité, lisibilité et esthétique.

Merci beaucoup pour ton aide qui m'a permis de trouver une solution et de continuer.

A plus sur d'autre topics j'espère