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

Composants VCL Delphi Discussion :

Champ integer à faire apparaître sous forme de chaîne


Sujet :

Composants VCL Delphi

  1. #1
    Membre émérite
    Champ integer à faire apparaître sous forme de chaîne
    Bonjour

    J'utilise Firedac dans Delphi Sydney.
    Une table dans ma base Firebird a une colonne de type Integer.
    J'affiche cette valeur dans une grille de saisie: TDBGrid

    En fait, ma valeur représente plusieurs états possibles:
    0 = non répondu
    1 = Oui
    2 = Non
    3 = Réponse attendue
    etc.

    Dans ma grille je vais utiliser une TDBCombobox qui apparaîtra au moment de la saisie pour une ligne.

    Problème: Dans ma grille et ma combo, je ne veux pas afficher 0, 1, 2 etc. mais les valeurs textes plus explicites.

    Il me semble qu'on pouvait faire ça mais je ne retrouve plus le moyen d'y arriver.

    Quelqu'un aurait une piste à me donner ?

  2. #2
    Membre expérimenté
    Tu peux tenter avec un champ calculé au niveau de ta table.

    L'autre solution serait d'utiliser les fonctions de formatage au niveau du lien Live Bindings, mais c'est pas hyper maintenable.

  3. #3
    Membre émérite
    Le champ calculé ? Pour l'affichage ça ira mais pour la modification avec la TDBCombobox, ça se passerait comment ?
    Pour moi, un champ calculé affiche un résultat de calcul justement, mais je pourrais vraiment mettre mon champ calculé dans la combo ?
    Ou alors, tu veux dire que la liste de choix ne serait pas liée à la table mais juste une liste de chaines et je pourrai gérer la valeur en fonction du choix ?

  4. #4
    Rédacteur/Modérateur

    Bonjour,

    Il me semble avoir déjà fait ça (âge oblige) en D3 il faut que je retrouve mes sources et dans quel(s) programme(s)
    Il me semble aussi que smDBGrid (visible elipsis and dropdown buttons for each record for Lookup-fields, PickLists etc ) propose une solution plus facile (si tu n'es pas allergique au produits tiers)
    Cela écrit ce ne sont que des "il me semble" d'un petit matin brumeux, que seul une recherche dans mes application confirmerait

    Déjà, s'il s'agit toujuors du même sujet avec Firebird, avec le SQL pas besoin de champ calculé pour l'affichage un CASE peut fonctionner
    SELECT
    --
    CASE REPONSE WHEN 0 then 'non répondu'
    WHEN 1 then 'Oui'
    WHEN 2 then 'Non'
    WHEN 3 then 'Réponse attendue'
    ...
    ELSE '?'
    END AS INTITULEREPONSE,
    --
    FROM TABLE
    la question de l'intitulé dans la grille sera donc réglé

    Pour la suite, attends-toi à un [Edit] de ma part, le reveil se fait petit à petit, mes premiers souvenirs me disent que j'utilisai un DBcombobox ou un combobox à part (bien positionné sur la grille) mais c'est encore nébuleux
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein

    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Tokyo, Rio, Sidney) et peut être quelques autres
    SGBD : Firebird 2.5, 3, SQLite
    générateurs Etats : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Ubuntu, Androïd

  5. #5
    Rédacteur/Modérateur

    J'ai fini par retrouver, dans un de mes plus vieux programme quelque chose qui ressemble à ta demande


    à l'époque c'est pas récent ça date de 1998 voilà ce que ça donnait

    cela dit je m'en sortais parce que le type était en fait un caractère et non un entier et cela ne dépassait 9 (1 ou 2) la chaine du 'combox' était tronquée

    Citation Envoyé par pprem
    L'autre solution serait d'utiliser les fonctions de formatage au niveau du lien Live Bindings,
    Je me demande comment je ferai maintenant avec les livebindings (ou sans d'ailleurs).
    le hic des Livebindings c'est que les IfThen imbriqués dans une expression cela ne le ferait pas (trop complexe) il faudrait faire une méthode spécifique (cf. mon deuxième ou troisième tuto sur le sujet https://serge-girard.developpez.com/...gs/Episode-2a/)
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein

    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Tokyo, Rio, Sidney) et peut être quelques autres
    SGBD : Firebird 2.5, 3, SQLite
    générateurs Etats : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Ubuntu, Androïd

  6. #6
    Membre émérite
    Donc, c'est possible.

    Les valeurs sont limitées à 5 pour moi.
    Il suffirait que j'utilise ce case dans la requête et la picklist qui va bien.
    La smdbgrid, j'y avais pensé mais elle a un drôle de comportement et je ne sais pas si ça vient de Sydney ou s'il y a un bug ou deux
    Par exemple, j'en avais posé 2 sur la tform et quand je cliquais sur une cellule de la première et ensuite sur la seconde, la valeur de la première cellule s'affichait dans le seconde :-(
    Alors, je me suis rabattu sur du standard.
    J'avais pensé à la rxlib dans la jvcl mais j'évite, parce que installer 600 composants pour en utiliser 1, je trouve _ça un peu excessif.

    Je vais essayer ta solution.

    Merci pour cette piste intéressante.

  7. #7
    Membre émérite
    Alors, j'ai bien la liste déroulante dans ma grille et la valeur affichée dans la colonne.
    Sauf que, au moment où je change de ligne et que l’enregistrement est "posté", je ramasse une ramasse une erreur indiquant que mon champ ajouté avec la case n'existe pas. Tu l'as surement compris, il s'agit de ma requête sur les résultats d'ag.

    C'est un peu normal puisque ce champ n'existe effectivement pas dans la table et que Firedac cherche à le mettre à jour :-(

    J'en suis pas loin .... Sinon, vu rien n'est encore livré, je modifierai le type de mon champ et il se transformera en chaîne de caractères qui reprendra les libellés plutôt que des entiers

  8. #8
    Rédacteur/Modérateur

    Bon, c'est mon jour kiné et ma séance va bientôt avoir lieu donc je ne peux pas répondre in extenso j'en suis à ceci

    il me reste à positionner le combobox de façon correcte
    Oui, j'ai commencé par les livebindings sur un StringGrid mais bon le test DBGrid est prévu

    Les trucs ?
    Le SQL
    Code SQL :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT 
     ID,TEXTE,REPONSE,
     CASE REPONSE 
      WHEN 0 THEN 'Non'
      WHEN 1 THEN 'Oui'
      WHEN 2 THEN 'Peut-être'
      WHEN 3 THEN 'Jamais'
     END TXTREP
    FROM QUESTIONS


    le FDUPdateSQL FetchRow
    Code SQL :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT ID, TEXTE, REPONSE,
    CASE REPONSE 
     WHEN 0 THEN 'Non'
     WHEN 1 THEN 'Oui'
     WHEN 2 THEN 'Peut-être'
     WHEN 3 THEN 'Jamais'
    END TXTREP
     
    FROM QUESTIONS
    WHERE ID = :OLD_ID


    et un peu de code
    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
    procedure TForm1.ComboBox1CloseUp(Sender: TObject); // ou peut-être onchange ? 
    begin
    FDQuery1.Edit;
    FDQuery1.FieldByName('Reponse').AsInteger:=Combobox1.ItemIndex;
    FDQuery1.Post;
    FDQuery1.Refresh;  //<<< c'est là le secret 
    end;
     
    procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
      var CanSelect: Boolean);
    begin
    if ACol=3 then
     begin
       Combobox1.ItemIndex:=FDQuery1.FieldByName('Reponse').AsInteger;
     //  Combobox1.Top:=;
     end;
    Combobox1.Visible:=ACol=3;
     
    end;

    Ce qui m'a toujours gêné dans cette méthode c'est qu'il faut faire attention à la répétition des intitulés des choix, dès que tu as à faire de la maintenance dessus tu te retrouves à écrire trois fois (2 sql+la liste)

    Mais sinon, ça le fait (enfin dès que j'aurai bien positionné le combo) c'est en allant sur la FAQ que j'ai vu tes deux nouveaux posts

    je modifierai le type de mon champ et il se transformera en chaîne de caractères qui reprendra les libellés plutôt que des entiers
    Moui, non, je trouve ça pas terrible surtout si après tu veux faire des calculs de groupe (GROUP BY) imagine si ton "client" veux changer un libellé
    je verrais plutôt une table des libellés réponse (ne serait-ce que pour répondre à ma critique de la méthode)
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein

    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Tokyo, Rio, Sidney) et peut être quelques autres
    SGBD : Firebird 2.5, 3, SQLite
    générateurs Etats : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Ubuntu, Androïd

  9. #9
    Membre émérite
    Profite de ton kiné, c'est la dernière chose qu'il me reste côté interface et il faut que je tape directement dans le code maintenant pour utiliser les choix de cette grille.
    ça peut attendre.

    J'ai déjà compris qu'il faudrait passer un updatesql

  10. #10
    Rédacteur/Modérateur

    Pour la position de la combobox
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
       Combobox1.Top:=StringGrid1.CellRect(ACol,ARow).Top;

    en lieu et place du commentaire, cela dit c'est à peine testé

    Pour ce qui est de DBGrid cela me parait un peu plus compliqué, j'ai rapidement fait ceci
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
      DataCol: Integer; Column: TColumn; State: TGridDrawState);
    begin
    if DataCol=3 then
     begin
       Combobox1.ItemIndex:=FDQuery1.FieldByName('Reponse').AsInteger;
       ComboBox1.Top:=Rect.Top;
       Combobox1.Left:=Rect.Left;
     end;
     ComboBox1.Visible:=(DataCol=3) AND (gdFocused in State);
    end;

    mais comme j'ai fait ça sur la même fiche que la StringGrid et avec le même combobox c'est pas terrible (niveau update)


    Quant à la réponse FMX elle est déjà dans mon tutoriel sur les Grilles FMX, un popupmenu
    Sur ce j'y vais
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein

    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Tokyo, Rio, Sidney) et peut être quelques autres
    SGBD : Firebird 2.5, 3, SQLite
    générateurs Etats : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Ubuntu, Androïd

  11. #11
    Rédacteur/Modérateur

    Solution popupmenu
    En parlant de PopupMenu c'est aussi valable pour VCL avec le même problème que la combobox : son placement sauf si tu estimes qu'un clic droit de la part de l'utilisateur n'est pas cher payé.

    Si le clic droit n'est "pas convenable" un petit hack (https://www.developpez.net/forums/d1.../#post10011077)
    et le tour est joué

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    THackGrid = class(TDBGrid)
       private
        function GetCellPos : TRect;
        function GetScreenCellPos: TRect;
       end;
     
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.DBGrid1CellClick(Column: TColumn);
    var R : TRect;
    begin
    if Column.Index=3 then
     begin
        R:= THackGrid(DBGrid1).GetScreenCellPos;
        PopupMenu1.Popup(R.Left,R.Top);
      end;
    end;
     
    procedure TForm1.PopupItemClick(Sender: TObject);
    begin
    FDQuery1.Edit;
    FDQuery1.FieldByName('Reponse').AsInteger:=(Sender as TMenuItem).MenuIndex;
    FDQuery1.Post;
    FDQuery1.Refresh;
    end;
     
    procedure TForm1.PopupMenu1Popup(Sender: TObject);
    begin
    PopupMenu1.Items.MenuIndex:=FDQuery1.FieldByName('Reponse').AsInteger;
    end;
     
    { THackGrid }
     
    function THackGrid.GetCellPos: TRect;
    begin
    Result:=CellRect(Col,Row);
    end;
     
    function THackGrid.GetScreenCellPos: TRect;
    begin
    Result.TopLeft:=ClientToScreen(GetCellPos.TopLeft);
    Result.BottomRight:=ClientToScreen(GetCellPos.BottomRight);
    end;


    Bon je suis crevé après ma séance, je pense que la réponse avec un Helper plutôt qu'un Hack serait encore mieux, mais comme je me souvenais de cette intervention.

    Ce qui nous fait au moins 3 solutions VCL si à cela tu blindes en rajoutant une table VALEUR_REPONSE(VALEUR SMALLINT NOT NULL PRIMARY KEY, LIBELLE_REPONSE VARCHAR(30)) mâtinée de contrainte réferentielle on arrive à quelque chose de potable. YAPLUKA faire un petit remplissage du Combobox ou du PopupMenu (selon le choix) en fonction de la table, modifier un peu le SQL (adieu le CASE bonjour le JOIN)
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein

    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Tokyo, Rio, Sidney) et peut être quelques autres
    SGBD : Firebird 2.5, 3, SQLite
    générateurs Etats : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Ubuntu, Androïd

  12. #12
    Rédacteur/Modérateur

    Alors, pour finaliser cela (sauf le helper car je ne sais plus comment faire) j'ai préparé une petite vidéo https://serge-girard.developpez.com/tutoriels/temp/Video_choix.webm
    Oui, il y a quelques petits couacs, faute à des cellules déjà sélectionnées mais dans la pratique ce ne devrait pas se produire
    En peaufinant un peu (jeu d'essai surtout) cela pourrait presque faire l'objet d'un tutoriel en y incluant ma solution de départ et la solution FMX en prime
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein

    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Tokyo, Rio, Sidney) et peut être quelques autres
    SGBD : Firebird 2.5, 3, SQLite
    générateurs Etats : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Ubuntu, Androïd

  13. #13
    Membre émérite
    2 solutions donc, avec TDBgrid ou STringGrid + LiveBindings.

    Pour être honnête, LiveBindings coince encore un peu dans ma tête.
    J'ai pourtant lu tes tutos mais il y a toujours un moment où je décroche.

    Et pour a dbgrid, en fait ça revient à utiliser une combo qui n'a rien à voir avec les composants de données mais juste à profiter de son contenu et son index pour traiter les valeurs. J'avoue que cette solution me plait mieux.
    Si j'ai bien compris il faut penser à adapter un peu les TFDUpdateSQL.

    Une chose que j'ai pendant mes différentes tentatives: Quand on utilise la picklist, les valeurs qui le remplissent sont bien proposées mais ça ne limite pas le choix. Elle n'empêche pas l'utilisateur d'écrire n'importe quoi au moment de l'édition. Il manquerait de pouvoir définir un style comme les combo standard.

    Je vais utiliser lé méthode combo , et promis, je me re pencherai sur les livebindings

    Merci à toi et pour le tuto basé sur tes reherches, je sis certain que ça aiderait d'autres comme moi

  14. #14
    Rédacteur/Modérateur

    Citation Envoyé par Papy214 Voir le message
    Si j'ai bien compris il faut penser à adapter un peu les TFDUpdateSQL.
    c'est le truc le plus important du lot

    Citation Envoyé par Papy214 Voir le message
    2 solutions donc, avec TDBgrid ou STringGrid + LiveBindings.
    3 si tu considères la version D3, 4 si tu choisi le PopupMenu plutôt qu'un combobox

    Citation Envoyé par Papy214 Voir le message

    Pour être honnête, LiveBindings coince encore un peu dans ma tête.
    J'ai pourtant lu tes tutos mais il y a toujours un moment où je décroche.
    Oui, livebindings c'est quand même un peu "différent" mais si tu te mets à FMX pas le choix

    Et pour a dbgrid, en fait ça revient à utiliser une combo qui n'a rien à voir avec les composants de données mais juste à profiter de son contenu et son index pour traiter les valeurs. J'avoue que cette solution me plait mieux.
    je préfère le popupmenu tant qu'à faire, il est vrai que je n'ai pas mis les sources de la vidéos mais c'est faisable

    Une chose que j'ai pendant mes différentes tentatives: Quand on utilise la picklist, les valeurs qui le remplissent sont bien proposées mais ça ne limite pas le choix. Elle n'empêche pas l'utilisateur d'écrire n'importe quoi au moment de l'édition. Il manquerait de pouvoir définir un style comme les combo standard.
    ah, mais ce n'était pas dans le cahier des charges c'est jouable

    Citation Envoyé par Papy214 Voir le message

    promis, je me re pencherai sur les livebindings
    promesse de 1° de l'an ?

    Merci à toi et pour le tuto basé sur tes reherches, je suis certain que ça aiderait d'autres comme moi
    Bon il est pas encore écrit mais je trouve que avec un peu de remaniement cela pourrait faire un bon sujet
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein

    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Tokyo, Rio, Sidney) et peut être quelques autres
    SGBD : Firebird 2.5, 3, SQLite
    générateurs Etats : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Ubuntu, Androïd

  15. #15
    Membre émérite
    promesse de 1° de l'an ?
    promesse de quand j'aurai le temps.
    Après deux mois d'arrêt + deux mois de travail en mi-temps thérapeutique, il y avait des choses à rattraper.
    Et je ne suis pas aussi en forme que je le voudrais, je fatigue vite :-(
    (mais ce n'est pas à toi que je vais apprendre les effets d'une santé défaillante)

###raw>template_hook.ano_emploi###