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

Bases de données Delphi Discussion :

Tri sur une colonne d'un champs calculé DBGRID


Sujet :

Bases de données Delphi

  1. #1
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut Tri sur une colonne d'un champs calculé DBGRID
    Bonjour à toutes et à tous,

    J'ai besoin de trier un dbgrid au clique sur les entete de colonne, jusque là rien de compliquer et tout fonctionne bien.

    Mais si je fais une requet de ce style

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Select CodeFacture, CodeArticle, Sum(Quantite) as SommeDeQte 
    From EnteteFacture
    Group By Codefacture, CodeArticle

    si je clique dans mon DBGrid sur la colonne codefacture ou codeArticle cela tri dans l'ordre croissant ou décroissant sans probleme grace à :

    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
    procedure TFTravail.DBGrid1TitleClick(Column: TColumn);
    begin
     
      With Query Do
      Begin
        Try
          SQL.Clear;
          Sql.Add(Requete.Text);
          if ColonneCliquee <> '' then
          Begin
            if Tri = ' ASC'
            Then Tri := ' DESC'
            else Tri := ' ASC';
            Sql.Add('Order By '+ Column.FieldName + Tri);
          end;
          Open;
     
    // Etc...
     
    end;

    Evidement si je clique sur la troisieme colonne nommé automatique en SommeDeQte, alors ADO renvoi un erreur puisqu'il ne trouve pas le field associé.

    Comment peut-on solutionner se problème ?

    - existe-t-il un moyen de faire un tri (order by) par le numero de champs, je connais Column.Index mais je vois pas comment m'en servir
    - dois-je parcouri les champs entre SELECT et FROM ? et m'amuse à récupérer le nom du champ entre les parenthèse ? (délicat si je cumul des requetes) ?

    avez-vous une idée ?

  2. #2
    Membre émérite
    Homme Profil pro
    Directeur technique
    Inscrit en
    Mai 2008
    Messages
    2 401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2008
    Messages : 2 401
    Points : 2 304
    Points
    2 304
    Par défaut
    Salut;

    je crois que tu as fais le plus dur. Néanmoins pour ton souci faudrait jouer avec le paramètre Column passé en argument.
    Bon courage ou Bonne Chance (selon le contexte)
    Mon blog sur WordPress

  3. #3
    Membre chevronné Avatar de philnext
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    1 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 552
    Points : 1 780
    Points
    1 780
    Par défaut
    En fait je ne vois pas pourquoi ça ne marcherait pas...ta colonne existe bien !

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 043
    Points : 40 957
    Points
    40 957
    Billets dans le blog
    62
    Par défaut
    Salut

    effectivement
    existe-t-il un moyen de faire un tri (order by) par le numero de champs
    moi je le fais par l'ordre des champs de la requête lorsqu'il s'agit de champs calculés

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT CodeFacture, CodeArticle, Sum(Quantite) AS SommeDeQte 
    FROM EnteteFacture
    GROUP BY Codefacture, CodeArticle
    ORDER BY 3

    Néanmoins je n'utilise ni Access, ni ADO donc .......?
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  5. #5
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Salut Serge,

    Comment vas-tu l'ami.

    Effectivement j'utilise cela dans Access directement et cela foctionne bien, mais avec ADO y-a rien à faire il accepte pas, ce serais génial de pouvoir l'appliquer. Est-ce lié au type de la base ? c'ets vraiment étrange que je puisse le faire dans access mais pas via une requete dans ado !!!

    Il y a surement un moyen de faire un order by autrement que par le nom d'un champ ?

    Philnext : le nom de la colonne ici SommeDeQte n'ai pas un champ de la base donc tu peux pas trié dessus.


    en fait pour que cela fonctionne je devrais faire
    SELECT CodeFacture, CodeArticle, Sum(Quantite) AS SommeDeQte
    FROM EnteteFacture
    GROUP BY Codefacture, CodeArticle
    Order By Sum(Quantite
    )

    mais c'est ingérable je doit m'amuser à décortiquer la requette !!!

    en résumé comment faire marché cela, qui marche sous access mais pas avec ADOQuery :
    SELECT CodeFacture, CodeArticle, Sum(Quantite) AS SommeDeQte
    FROM EnteteFacture
    GROUP BY Codefacture, CodeArticle
    Order By 3


    PS : Serge (j'ai pas encore mis en plce tes modifs, beaucoup de taf et d'autre réglage à faire. Dés que j'ai fini je te montrerais. Merci encore pour ton implication.

  6. #6
    Membre émérite
    Homme Profil pro
    Directeur technique
    Inscrit en
    Mai 2008
    Messages
    2 401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2008
    Messages : 2 401
    Points : 2 304
    Points
    2 304
    Par défaut
    Re;

    désolé mon ami j'avais loupé ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Sql.Add('Order By '+ Column.FieldName + Tri);
    Donc je retire ce que j'ai dis car c'est déjà pris en compte. Mais je m'implique dans le combat car très intéressant si on pouvait arriver à une solution.
    Bon courage ou Bonne Chance (selon le contexte)
    Mon blog sur WordPress

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 560
    Points : 576
    Points
    576
    Par défaut
    Bonjour,

    A priori, il est normal que cela plante.
    Lorsque vous entrer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT CodeFacture, CodeArticle, Sum(Quantite) AS SommeDeQte 
    FROM EnteteFacture
    GROUP BY Codefacture, CodeArticle
    Le select connait CodeFacture, CodeArticle au fur et a messure ce qui permet un trie.
    Par contre il ne connait SommeDeQte qu'après avoir terminé la selection des champs (calcule terminé uniquement à la fin du select) et ne peut donc pas le trier au fur et a mesure. C'est pour cela que la fonction HAVING à été implémenter. (voir http://sqlpro.developpez.com/cours/sqlaz/ensembles/#L2)

    Il ce peut que certain SQL soit plus permissif, mais ce ne doit pas être dans la norme.

    Avez vous penser a essayer de créer une vue avec votre code SQL ? Vous devriez pouvoir appeler votre vus avec tout les filtres et les trie que vous désirez.

  8. #8
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut

    je suis surpris que cette requette ne fonctionne pas
    la syntaxe sql faisant parti de norme sql92

    voici une méthode toute faite
    tu peut soit passer par les column soit nommer le champs manuellement
    je m'en sert lorsque j'ajoute des champs calculer au Tquery
    c'est champs n'ayant pas de champs sous-jacent dans la requette


    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
     
    procedure TriColonneSql(Column: TColumn;Ordre :String);
    var
      ligne :integer;
      rq :Tquery;
      Trouve: boolean;
    begin
      if column.FieldName='' then exit;
      if column.Field.DataSet=Nil then exit;
      rq := TQuery(column.Field.DataSet);
      if (rq.State = dsBrowse) or (rq.State= dsInactive) then
      begin
        if ordre='' then
          ordre := column.FieldName;
        ligne := 0;
        Trouve := False;
        // determine le numero de ligne
        repeat
          inc(ligne);
          if pos('ORDER BY',UpperCase(rq.SQl.strings[ligne]))<>0 then
          begin
            Trouve := True;
            break;
          end;
        until ligne=rq.SQL.count-1;
     
        if Trouve then
        begin
          if (pos(ordre,UpperCase(rq.SQl.strings[ligne]))<>0) and 
             (pos('DESC',UpperCase(rq.SQl.strings[ligne]))=0) then
          begin
             if (pos(',',Ordre)<>0) then
               ordre := copy(Ordre,1,pos(',',Ordre)-1)+ ' DESC '
                   + copy(Ordre,pos(',',Ordre),length(ordre))
             else
               ordre := ordre + ' DESC';
             rq.SQl.strings[ligne] := 'ORDER BY '+Ordre;
          end
          else 
            rq.SQl.strings[ligne] := 'ORDER BY '+Ordre;
        end
        else
           rq.SQL.Add('ORDER BY '+ordre);
       end;
    end;
    @+ Phil
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  9. #9
    Membre habitué Avatar de abdelghani_k
    Inscrit en
    Octobre 2002
    Messages
    184
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Octobre 2002
    Messages : 184
    Points : 150
    Points
    150
    Par défaut
    Bonjour à tout le monde,

    J'ai appliqué votre cas sur un exemple, chez moi ca marche bien.
    voici le 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
    20
    21
    22
     
    procedure TFfac.DBGrid1TitleClick(Column: TColumn);
    begin
      With DM1.ADOSelectFAC Do
      Begin
        Try
          SQL.Clear;
          Sql.Add(Requete.Text);
          //showmessage(Column.FieldName);
          //if ColonneCliquee <> '' then
          Begin
            if Tri = ' ASC'
            Then Tri := ' DESC'
            else Tri := ' ASC';
            Sql.Add(' Order By '+ Column.FieldName + Tri);
          end;
          Open;
        finally
           //...
        end;
      end
    end;
    voici la requete (requete.text) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT FACTURE,ARTICLE,SUM(QTE) AS QTESOMME FROM FACTURES GROUP BY FACTURE, ARTICLE
    Mais pour :
    Citation Envoyé par BuzzLeclaire Voir le message
    Evidement si je clique sur la troisieme colonne nommé automatique en SommeDeQte, alors ADO renvoi un erreur puisqu'il ne trouve pas le field associé.
    Quel est le message d'erreur exactement ?
    Réussir c'est faire le bon choix.

    Voici ma supper fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Fonction ChercherSolution(User_id:login in www.developper.com):Vrai;

  10. #10
    Membre habitué Avatar de abdelghani_k
    Inscrit en
    Octobre 2002
    Messages
    184
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Octobre 2002
    Messages : 184
    Points : 150
    Points
    150
    Par défaut
    Tout simplement :

    Dans l'inpecteur d'objet de ADOQuery, aprés la saisie de cette requete dans SQL:

    SELECT FACTURE,ARTICLE,SUM(QTE) AS QTESOMME
    FROM LIG_FAC GROUP BY FACTURE, ARTICLE
    ORDER BY QTESOMME DESC

    puis j'ai mis Active à True aucun message d'erreur donc ca marche.

    Je crois que tu dois revoir les colonnes de ta DBGrid et leurs associations aux fileds de ADOQuery.
    Réussir c'est faire le bon choix.

    Voici ma supper fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Fonction ChercherSolution(User_id:login in www.developper.com):Vrai;

  11. #11
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Bonjour et merci,

    Explication de fonctionnement de mon prog :

    La requete est tapée dans un RichEdit appelé requete.

    Exemple de requete :
    Requete.Text = Select Codefacture, CodeArticle, Sum (Quantite) as SommeDeQte From [Ligne CI]
    Group By CodeFacture, CodeArticle


    Alors,
    abdelghani_k :
    Le message d'erreur d'ADO au clic sur la colonne SommeDeQte est :
    --- Message d'erreur :
    Type Erreur : EOleException
    Message : Le paramètre SommeDeQte n'a pas de valeur par défaut

    Pour cette affirmation :
    "Je crois que tu dois revoir les colonnes de ta DBGrid et leurs associations aux fileds de ADOQuery. "
    Il n'y a aucune association. C'est une requete à la voléé taper par l'utilisateur.

    Concretement
    L'utilisateur ouvre la table, tape une requete dans un trichedit, clique sur un bouton actualisé et le Dbgrid ce rempli par rapport à cette requete (rien n'ai définie à l'avance)

    Tardiff Jean-François :
    La clause HAVING je n'utilise pas ici, je n'ai pas besoin de filtre apres regroupement, de plus cette clause serais dans le cas de son utilisation placer apres order by biensur.

    anapurna :
    Je vais me pencher sur ta proposition, merci.


    @+

  12. #12
    Membre habitué Avatar de abdelghani_k
    Inscrit en
    Octobre 2002
    Messages
    184
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Octobre 2002
    Messages : 184
    Points : 150
    Points
    150
    Par défaut
    Bonjour,

    L'application de votre exemple qui marche a été avec une base de données SQL server.
    Lorqsque j'ai changé la base en access et la chaine de connexion de ADO j'ai recu ce message d'erreur EOleException.

    Mais avec la proposition de Serge 5trier selon les numéros de colonne) ca fonctionne même avec Access :
    Citation Envoyé par SergioMaster Voir le message
    Salut

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT CodeFacture, CodeArticle, Sum(Quantite) AS SommeDeQte 
    FROM EnteteFacture
    GROUP BY Codefacture, CodeArticle
    ORDER BY 3
    Réussir c'est faire le bon choix.

    Voici ma supper fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Fonction ChercherSolution(User_id:login in www.developper.com):Vrai;

  13. #13
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Je reviens rapidement vous donner le résultat de ce parcours.

    Je vois entre temps que Abdel a touché le point sensible précité par Serge mon acolyte

    D'ailleur je disais bien plus haut que j'arrivais à le faire fonctionner dans ACCESS mais pas avec ADO...

    Voilà ce que je faisais lors du group by provenant d'une saisie aléatoire d'un utilisateur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    { Pour info ColonneCliqueRef est Integer équivaut à Column.index }
    With Query Do
      Begin
        Try
    // ...
    // ...
            Sql.Add(' Order By :xRef :xTri');
           Parameters.ParamByName('xRef').Value := ColonneCliqueeRef;
           Parameters.ParamByName('xTri').Value := Tri;
    // ...
          Open;
    Ou même cela

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    { Pour info ColonneCliqueRef est Integer équivaut à Column.index }
    With Query Do
      Begin
        Try
    // ...
    // ...
           St := Requete.Text + ' Order By %d ' + Tri);
            Sql.Add(Format(St,[ColonneCliqueeRef]);
     
    // ...
          Open;
    Apres avoir essayer pas mal de différent parametre j'en suis revenu à cela
    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
      With Query Do
      Begin
        Try
          Close;
          SQL.Clear;
          Sql.Add(Requete.Text);
          if ColonneCliqueeRef >= 0 then
          Begin
            if (ColonneCliqueeRef = ColonneCliqueeRefOld) Then // on clique sur la meme colonne 'reclic'
            Begin
              if Tri = ' ASC'
              Then Tri := ' DESC'
              else Tri := ' ASC';
            end
            else
              Tri := ' ASC';
            Sql.Add(' Order By '+ InttoStr(ColonneCliqueeRef+1) + Tri);
          end;
          Open;
    Je l'avais pourtant déjà essayé !!!
    Mais j'oubliais que la colonne 0 vaut le champ 1....

    Merci à toutes et à tous pour votre implication et à la recherche de solution.

    J'ai pu avancée nettement dans mon projet.

    Serge

  14. #14
    Membre habitué Avatar de abdelghani_k
    Inscrit en
    Octobre 2002
    Messages
    184
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Octobre 2002
    Messages : 184
    Points : 150
    Points
    150
    Par défaut
    Voila ce que j'ai pu trouvé encore (à essayer c joli) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    procedure TForm1.DBGrid1MouseMove
      (Sender: TObject; Shift: TShiftState; X, Y: Integer);
    var
      pt: TGridcoord;
    begin
      pt:= DBGrid1.MouseCoord(x, y);
     
      if pt.y=0 then
        DBGrid1.Cursor:=crHandPoint
      else
        DBGrid1.Cursor:=crDefault;
    end;
    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
     
    procedure TForm1.DBGrid1TitleClick(Column: TColumn);
    {$J+}
     const PreviousColumnIndex : integer = 0;
    {$J-}
    begin
      if DBGrid1.DataSource.DataSet is TCustomADODataSet then
      with TCustomADODataSet(DBGrid1.DataSource.DataSet) do
      begin
        try
          DBGrid1.Columns[PreviousColumnIndex].title.Font.Style :=
          DBGrid1.Columns[PreviousColumnIndex].title.Font.Style - [fsBold];
        except
        end;
     
        Column.title.Font.Style :=
        Column.title.Font.Style + [fsBold];
        PreviousColumnIndex := Column.Index;
     
        if (Pos(Column.Field.FieldName, Sort) = 1)
        and (Pos(' DESC', Sort)= 0) then
          Sort := Column.Field.FieldName + ' DESC'
        else
          Sort := Column.Field.FieldName + ' ASC';
      end;
    end;
    Réussir c'est faire le bon choix.

    Voici ma supper fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Fonction ChercherSolution(User_id:login in www.developper.com):Vrai;

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 8
    Dernier message: 23/05/2012, 20h24
  2. Réponses: 9
    Dernier message: 10/02/2011, 10h25
  3. tri sur une colonne
    Par cubepiege dans le forum Langage SQL
    Réponses: 11
    Dernier message: 13/07/2006, 12h16
  4. tri sur une partie d'un champ
    Par yoline dans le forum Access
    Réponses: 4
    Dernier message: 19/09/2005, 11h25
  5. [JSP] tri sur une colonne
    Par soony dans le forum Servlets/JSP
    Réponses: 6
    Dernier message: 28/07/2005, 15h02

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