IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++Builder Discussion :

Récupérer la couleur d'une celule d'un DBGrid


Sujet :

C++Builder

  1. #1
    Membre Expert
    Avatar de sat83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2004
    Messages
    1 040
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 040
    Par défaut Récupérer la couleur d'une celule d'un DBGrid
    Bonjour a tous!

    Pour un affichage coloré de mon DBGrid, je colore les cellules pour mettre en avant certains champ (via OnDrawColumnCell ).

    Par contre j'aimerais savoir comment récupérer la couleur des cellules du DBGrid (pour faire un export)? La récupération des données est facile (une simple boucle while sur le TDataSet), mais pour la couleur des cellules je ne vois pas comment faire?

    Pour récupérer la n-ième colonne de la ligne en cours:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DBGrid1->Columns->Items[n]->Field->DisplayText
    Avez-vous une idée pour récupérer le couleur de la cellule? (C'est peut être facile, mais je vois pas!)

    Merci d'avance pour votre aide!

  2. #2
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    Salut sat83
    Je ne sais pas comment tu procede pour colorer tes cellules, mais le principe doit etre le meme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    TColor couleur;
     
    // pour colorer
    StringGrid1->Canvas->Brush->Color = TColor(0xFFE0FF);
    // pour recuperer la couleur
    couleur = StringGrid1->Canvas->Brush->Color;
    pour une cellule il faut recuperer le brosse qui a paint la cellule

  3. #3
    Membre Expert
    Avatar de sat83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2004
    Messages
    1 040
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 040
    Par défaut
    Alors pour coloré les cellule de mon DBGrid dans le OnDrawColumnCell je fais par exemple :

    //coloration des lignes dont la valeur de "MonChamp" vaut 2 en vert + mise en italique (le DBGrid est relié à Query1)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    void __fastcall TForm1::DBGrid1DrawColumnCell(TObject *Sender,
          const TRect &Rect, int DataCol, TColumn *Column, TGridDrawState State)
    {
     
      if( Query1->FieldByName("MonChamp")->AsInteger == 2 )
      {
         DBGrid1->Canvas->Brush->Color= clGreen ;
         DBGrid1->Canvas->Font->Style = TFontStyles()<< fsItalic ;
      }
     
      try
      {
         DBGrid1->DefaultDrawColumnCell( Rect, DataCol, Column, State );
      }
      catch (...) { /* DO NOTHING */ }
    }
    Par contre pour récupérer la couleur d'une cellule (en parcourant tout mon DBGrid) je n'y arrive pas.

    pour une cellule il faut recuperer le brosse qui a paint la cellule
    Comment recupère t'on une cellule d'un DBGrid?

  4. #4
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    Pour colorer la cellule selectionner on fait ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol,
          int ARow, TRect &Rect, TGridDrawState State)
    {
    if(State.Contains(gdSelected))
    {
    // Les cellules sélectionnées sont en bleue
    StringGrid1->Canvas->Brush->Color = clNavy;
    StringGrid1->Canvas->Brush->Style = bsSolid;
    StringGrid1->Canvas->FillRect(Rect);
    }
    le reste du code
    }
    Je n'ai pas eut le temps de tester, maisc'est quand la cellule est selectionnee que je recuperais la couleur

  5. #5
    Membre Expert
    Avatar de sat83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2004
    Messages
    1 040
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 040
    Par défaut
    Je réexplique ce que je souhaiterais faire :

    J'ai un DBGrid contenant le résultat d'une requête (TQuery). Certaines lignes de ce DBGrid sont en couleurs (via OnDrawColumnCell voir exemple dans mon précedant post).

    Je suis en train de développer une fonction d'export vers Excel du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void DBGridToExcel( TDBGrid * aGrid, AnsiString aDestinationFileName )
    {
      TDataSet *ds ;
      ds = aGrid->DataSource->DataSet ;
      //[...]
      // Export vers EXCEL et sauvegarde du fichier
      //[...]
    }
    Ma fonction fonctionne parfaitement et exporte exactement le contenu de mon DBGrid vers Excel (titres des colonnes, tailles des colonnes, données, etc...)

    Ce que je souhaiterais faire, c'est également prendre en compte la Police (Font) et la couleur de fond de chaque cellule de mon DBGrid pour la reproduire dans Excel.

    La solution serait d'utiliser les même critères utilisés dans le OnDrawColumnCell de mon DBGrid et les mettre dans ma fonction d'Export. Le problème c'est que je souhaite faire un export "générique" d'un DBGrid quelconque, et donc je ne connais pas a l'avance les critères de coloration.

    Donc le problème : J'aimerais savoir comment récupérer la police et la couleur de fond des cellules d'un DBGrid dynamiquement (en gros j'ai un pointeur sur un DBGrid quelconque dont je ne connait rien, et je voudrait récupérer la police et la couleur de fond de chaque cellule).

    Je pense qu'il dois bien avoir un moyen, mais je commence à me demander si c'est possible

    .

  6. #6
    Membre éprouvé
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Par défaut
    Salut sat83,

    Peut être un début de solution, même si je ne sais pour le moment comment optimiser les retours.

    .h:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    AnsiString __fastcall GetPropCol(TDBGrid * aGrid, int idx_col, String propTarget);
    .cpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    AnsiString __fastcall TForm3::GetPropCol(TDBGrid * aGrid, int idx_col, String propTarget)
    {
    AnsiString result;
    		TColumn *pCol = aGrid->Columns->Items[idx_col];
    		//pCol->Font->Color = clGreen;
    			TPropInfo **propList;
    			int propcount = GetPropList(pCol, propList);
    			for (int i = 0;i < propcount; i ++)
    			{
    				if (propList[i]->Name.operator AnsiString()== propTarget)
    				{
    					try
    					{
    						result = VarToStr( GetPropValue(pCol->Font, propTarget) );
    					}
    					catch(EPropertyError &propError)
    					{
    						//catcher l'erreur sur propriété non dispo
    					}
    				}
    			}
    return result;
    }
    //-------------------------------------------------------
    void __fastcall TForm3::Button12Click(TObject *Sender)
    {
    ShowMessage( GetPropCol(DBGrid1, 0, "Color") );
    }
    En décommentant la ligne " //pCol->Font->Color = clGreen; ", et en changeant les valeurs, on peut voir que les résultats bougent, maintenant comment les interprêter pour les retransmettre a Excel, je ne sais pas pour le moment.

    Mais ... j'espère que tu pourras exploiter ce bout code...
    @+

  7. #7
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    Normalement, il faut considérer que les outils qui ont servi à dessiner la cellule sont perdus car remplacés au fur et à mesure !
    Par contre, on sait que chaque cellule se positionne en un endroit précis de la grille.
    Voici ce que l'on hérite de TCustomGrid :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Windows::TRect __fastcall CellRect(int ACol, int ARow);
    Si la cellule spécifiée n'est pas visible, CellRect renvoie un rectangle vide.
    Donc ... en principe, "yapluka" tester avec Canvas->Pixels !

    A plus !

  8. #8
    Membre éprouvé
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Par défaut
    Je me demande si on peut utiliser la valeur renvoyé par l'essai que j'ai fait dans les méthodes formattage des cellules Excel données : ici.

    Le problème étant que je me situe au niveau du champs entier et pas au niveau "individuel" de chaque cellule.

    ++

  9. #9
    Membre Expert
    Avatar de sat83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2004
    Messages
    1 040
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 040
    Par défaut
    Merci a vous deux pour vos réponses, je testerai vos propositions courant de la semaine (je n'ai pas C++ Builder sous la main en ce début de semaine).

    Pour la solution de henderson j'avais déja tester CopyRect et Canvas->Pixels, mais je retrouvais toujours la couleur par défaut du DBGrid (clWhite) même sur les cellules colorés. Je vais quand même continuer d'explorer de ce coté là.

    Dans tout les cas je regarde, je teste, et je vous tient au courant.

  10. #10
    Membre éprouvé
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Par défaut
    Bonjour,

    Je suis (ou du moins j'en ai l'impression) bloqué dans une situation similaire:
    . en réalité, je n'arrive a récupérer les informations "que" de l'objet TColumn, mais si jamais l'affichage est modifié via un évènement "OnDraw_machinChose", je n'arrive pas a récupérer la valeur affichée par l'objet (que ce soit le background color, les propriétés de font ou autre).
    Je n'ai que les valeurs "par défaut" de l'objet TColumn sous jacent.

    Une idée bizarre, et surement trop "lourde": ne peut on pas imaginer maintenir en mémoire un tableau des différentes valeurs qu'il te faut réacceder (que ce soit color ou font ou autre), tableau qui serait renseigné / modifié au moment du dessin de la grille ? De cette manière, tu peut garder les "vraies" valeurs travaillées via le canvas.

    @+

  11. #11
    Membre Expert
    Avatar de sat83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2004
    Messages
    1 040
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 040
    Par défaut
    Citation Envoyé par Sunchaser Voir le message
    Une idée bizarre, et surement trop "lourde": ne peut on pas imaginer maintenir en mémoire un tableau des différentes valeurs qu'il te faut réacceder (que ce soit color ou font ou autre), tableau qui serait renseigné / modifié au moment du dessin de la grille ? De cette manière, tu peut garder les "vraies" valeurs travaillées via le canvas.
    Ca pourrait etre une solution, mais effectivement très lourde a mettre en place, et dans mon cas ca ne convient pas a ce que je souhaite faire. Et puis quitte a mettre en place une "sauvegarde" en mémoire de tous les éléments de Font et de couleur du DBGRid, je pense qu'il vaut mieux encore dérivé le composant DBGrid et créer un nouveaux composant intégrant ses propriétés.

    Malheureusement dans mon cas je souhaiterais garder le DBGrid de base pour pouvoir simplement ajouter des fonctions d'export a des programmes existants (utilisant DBGrid) sans trop de modifications.

    Donc je continu de chercher!

  12. #12
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    En fait, il y a une solution qui consiste à mémoriser les info directement dans la chaîne de la cellule.
    On pourrait ainsi en extraire ce qui doit être affiché et ce qui y contribue.
    Ca suppose de prendre en charge le dessin de toutes les cellules.

    A plus !

  13. #13
    Membre Expert
    Avatar de sat83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2004
    Messages
    1 040
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 040
    Par défaut
    Bon, je viens faire état de mon avancement pour ceux que ca intéresse !

    Alors pour la couleur de fond des cellules, la solution consistant a utiliser CopyRect et Pixels fonctionne, mais c'est assez lourd à mettre en œuvre pour avoir un truc "réutilisable". Pour récupérer la police, je n'ai pas trouver de solution satisfaisante. J'ai donc abandonné cette piste.

    Effectivement la solution consistant à enregistrer la couleur et la police directement dans la chaine de cellule était une bonne piste, mais c'est pareil je ne l'ai pas approfondie plus que ça car trop lourde à mettre en place dans mes projets.

    Finalement j'en suis arrivé a une solution qui ne correspond pas vraiment a ce que je souhaitais au départ, mais qui me convient bien pour le moment :

    Je définit un type de fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef void MaFonctionDeColoration( TDBGridColumns *col, TFont *f, TColor &c ) ;
    Et ma fonction d'export qui etait avant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void DBGridToExcel( TDBGrid * aGrid, AnsiString aDestinationFileName )
    devient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void DBGridToExcel( TDBGrid * aGrid, AnsiString aDestinationFileName, MaFonctionDeColoration*aFunction  )
    Donc dans mes projets j'implémente une fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void ColorCellule( TDBGridColumns *aCol, TFont *aFont, TColor &aColor )
    {
     // TESTE ET RENVOI LA COULEUR ET LA POLICE ADEQUAT
     // (fonction équivalente à ce qui se trouve dans OnDrawColumnCell)
    }
    Ca me permet sans trop de modif (j'ai juste a écrire la fonction ColorCellule en m'inspirant très fortement de OnDrawColumnCell) de pouvoir faire un export vers EXCEL Coloré!

    Cette solution me satisfait pour mes besoins personnels.

    Je ne met pas ce post en [Résolu] pour le cas où une personne passerait par là et proposerait une autre solution, mais de mon coté j'ai résolu mon problème.

    Merci encore a tous.

  14. #14
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    Salut sat83
    Je ne sais pas si cela va t'aider, mais j'ai lance une application contenant juste un StringGrid editable, j'ai lance Spy++ et verifie le Handle du StringGrid vide, des que l'on ecrit dans une ou plusieurs cellules il y a un seul Handle qui s'ajoute nomme " TInplaceEdit "

  15. #15
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    Le TInplaceEdit est un objet (dans le genre TEdit) qui vient se placer par dessus la cellule pour permettre la saisie du texte (Options << goEditing).
    Je ne suis pas sûr qu'il prenne la couleur de la cellule pour en faire son propre arrière plan !

    On supposant que l'opération soit effectuée très souvent, on aurait intérêt à développer une méthode et pourquoi pas pour une classe dérivée !

    L'objet arrivera assez facilement à faire, une fois pour toutes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    TColor __fastcall zeDBGrid::BackGroundCellColor(int ACol, int ARow)
    {
    TRect R = CellRect(ACol, ARow);
    //L'idéal est de pouvoir faire
    return Canvas->Pixels[R.Left][R.Top];
    //Mais il faut tester pour le meileur des cas et le pire !
    }
    Pour l'usage, comme on ne fait que rajouter une méthode, on a une modélisation relativement simple, car, ici, cette classe ne va servir qu'à transtyper :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class zeDBGrid : public TDBGrid
    {
    public :
    TColor __fastcall BackGroundCellColor(int ACol, int ARow); 
    //... d'autres méthodes dans le même genre...   
    };
    Donc à l'usage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    zeDBGrid *MyDBGrid;
    //------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
    //Une fois fait, ce n'est plus à faire
    MyDBGrid = (zeDBGrid*)DBGrid1;
    }
    //------------------ Pour tester
    void __fastcall TForm1::Panel1Click(TObject *Sender)
    {
    TPanel *Panel = (TPanel*)Sender;
    Panel->Color = MyDBGrid->BackGroundCellColor(1, 1);
    }
    Donc à ce stade on est loin de tes craintes d'avoir à faire à une usine à gaz !

    Sans doute que la solution idéale est du coté de Sunchaser ... mais il faudrait (je pense) envisager de développer une nouvelle classe en y gérant un tableau d'objets (la cellule en tant qu'objet gérée par EXCEL) et non un tableau d'AnsiString !

    A ce stade ... je ne sais pas !
    Par contre, il y a bien WOTSIT... mais je n'ai pas le temps d'aller farfouiller ... et je ne sais pas si le infos seraient utiles (EXCEL enregistre t-il les cellules de la même manière qu'il les gère ???)

    A plus !

Discussions similaires

  1. [XL-2010] Récupérer la couleur d'une case excel, pour l'appliquer lors d'une mise en forme
    Par interfector1st dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 07/06/2015, 00h24
  2. Récupérer les couleurs d'une image
    Par benthebest dans le forum Android
    Réponses: 2
    Dernier message: 06/02/2012, 23h33
  3. Récupérer la couleur d'une cellule et l'affecter à une autre
    Par Prue dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 20/08/2008, 17h04
  4. Comment donne une couleur a une ligne dans un DBGrid
    Par samy84s dans le forum Composants VCL
    Réponses: 5
    Dernier message: 14/09/2005, 23h22
  5. Récupérer la couleur d'une cellule excel par Delphi
    Par teamsebracing dans le forum API, COM et SDKs
    Réponses: 3
    Dernier message: 05/06/2003, 14h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo