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

 Delphi Discussion :

Filtrer une table en comparant deux champs entre eux


Sujet :

Delphi

  1. #1
    Membre régulier
    Inscrit en
    Avril 2008
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 167
    Points : 89
    Points
    89
    Par défaut Filtrer une table en comparant deux champs entre eux
    Bonjour à tous.

    Je veux filtrer une table en comparant deux champs de la table (par exemple le montant d'une facture et le montant du versement ie les factures non soldées) sans avoir à créer un troisième champ solde.

    En effet quand je filtre sur un champ seul par rapport à une constante ça marche, mais dès que je compare deux champs entre eux je reçois le message :"Opération non applicable".

    Merci.

  2. #2
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Quel est le filtre que tu appliques pour les deux champs à la fois et qui te génère cette erreur ?
    La FAQ - les Tutoriels - Le guide du développeur Delphi devant un problème

    Pas de sollicitations techniques par MP -

  3. #3
    Membre régulier
    Inscrit en
    Avril 2008
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 167
    Points : 89
    Points
    89
    Par défaut Filtrer une table en comparant deux champs entre eux
    La table a pour nom : tbFacture
    le 1er champ "montant versé" : MontantVerse
    Le 2ème champ "Montant en TTC" :MontantTTC
    et je veux avoir la liste des factures non soldées


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    tbFacture.Filter:='MontantVerse<MontantTTC';
    tbFacture.Filtered:=True;


    Je reçois le message : "Opération non applicable"

  4. #4
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 170
    Points
    4 170
    Par défaut
    Dit comme ça, ça a l'air correcte.

    Tu es sûr de l'orthographe des champs ?
    Est-ce que les deux champs sont du même type, est-ce que les types sont comparables ?

    Tu travailles avec quels composants ? quels SGBD ?

  5. #5
    Membre régulier
    Inscrit en
    Avril 2008
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 167
    Points : 89
    Points
    89
    Par défaut Filtrer une table en comparant deux champs entre eux
    Je travaille avec Delphi 7
    la Base de Données : BDE
    Fichier : Paradox
    Composant : TTable.

    Je suis sur de l'orthographe puis que je ramène le nom des champs par un Copier/Coller.

    Le deux champs sont numériques.

    Si je prends les champs séparément en posant par exemple comme filtre le montant de l'un ou de l'autre champ inférieur à une valeur constante cela marche.
    Mais si je prends la différence des deux champs en posant comme condition la différence négative ou l'un inférieur à l'autre, il sort alors le message "arithmétique non supportée par le filtre" pour le premier cas et "opération non applicable" pour le deuxième

  6. #6
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut

    A priori je ne vois pas d'erreur dans l'expression de ton filtre. Tu peux essayer en passant par l'évènement OnFilterRecord du DataSet:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TForm1.tbFactureFilterRecord(DataSet: TDataSet;
      var Accept: Boolean);
    begin
      with DataSet do
        Accept := FieldByName('MontantVerse').AsCurrency < FieldByName('MontantTTC').AsCurrency;
    end;
    @+ Claudius

  7. #7
    Membre régulier
    Inscrit en
    Avril 2008
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 167
    Points : 89
    Points
    89
    Par défaut Filtrer une table en comparant deux champs entre eux
    Exact, c'était la solution et le help de OnFilterRecord le confirme :

    Utilisez un gestionnaire d'événements OnFilterRecord pour filtrer les enregistrements en utilisant un critère ne pouvant être implémentéen utilisant la propriété Filter.Par exemple,en utilisant la propriété Filter, les comparaisons de champs ne sont pas autorisées pour les tables locales (Paradox, dBASE, Access, FoxPro) alors qu'un gestionnaire d'événements OnFilterRecord peut implémenter toute forme de critère.
    Il y a cependant un inconvéniant. Losque le filtrage est activé par la propriété Filtered a la valeur true, tous les autres filtres sur la table tdFacture subissent cette condition.

    En d'autres termes si on veut avoir toutes les factures d'un même Client on les a mais sans les factures soldées.

    j'ai essayé d'initialiser la variable 'accept' et je lui donne la valeur False lorsque je filtre sur les factures d'un même client ça me donne toujours les factures remplissant seulement la condition de OnFilterRecord, les autres factures du Client ne remplissant pas la condition de OnFilterRecord sont omises.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    procedure TForm1.tbFactureFilterRecord(DataSet: TDataSet;
      var Accept: Boolean);
     begin
        If Accept then
        begin
          with DataSet do
          Accept := FieldByName('MontantVerse').AsCurrency < 
                        FieldByName  'MontantTTC').AsCurrency;
         end;
    end;
    Comment alors rendre dans l'application, le filtre OnFilterRecord inactif lorsqu'un autre filtre utilisant la propriété Filtre est activé;

  8. #8
    Membre régulier
    Inscrit en
    Avril 2008
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 167
    Points : 89
    Points
    89
    Par défaut Filtrer une table en comparant deux champs entre eux
    autant pour moi!

    Il fallait initialiser une variable autre que accept pour que ça marche ( par exemple NonSolde). En effet avec le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    procedure TForm1.tbFactureFilterRecord(DataSet: TDataSet;
      var Accept: Boolean);
     begin
        If NonSolde then
        begin
          with DataSet do
          Accept := FieldByName('MontantVerse').AsCurrency < 
                        FieldByName  'MontantTTC').AsCurrency;
         end;
    end;

    Le résultat est Total.
    Si on veut filtrer sur autre chose que les factures non soldées, on fixe 'NonSolde' à False, sinon on lui donne la valeur True.

    Merci à tous.

  9. #9
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Re,

    Le filtre effectué par OnFilterRecord n'exclut pas la condition exprimée par la propriété Filter. Les 2 filtres "s'accumulent".

    Donc je te propose ceci: de faire fonctionner l'un ou l'autre. Soit la condition de Filter ou le traitement de OnFilterRecord.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure TForm1.tbFactureFilterRecord(DataSet: TDataSet;
      var Accept: Boolean);
    begin
      if DataSet.Filter <> '' then
        Accept := True
      else
        Accept := FieldByName('MontantVerse').AsCurrency < FieldByName('MontantTTC').AsCurrency;
    end;
    Ainsi si tu précise un Code Client dans la propriété Filter tu obtiendras toutes ses factures.
    A l'inverse lorsque Filter est vide ('') tu obtiendras uniquement les factures non soldées tous clients confondus.

    Je n'ai pas testé, mais cela devrait fonctionner.

    @+ Claudius

  10. #10
    Membre régulier
    Inscrit en
    Avril 2008
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 167
    Points : 89
    Points
    89
    Par défaut Filtrer une table en comparant deux champs entre eux
    Exact.
    J'avais remarqué que les deux filtres se cumulaient.
    Il fallait que lorque l'un est actif l'autre devait être inactif. Moi j'avais trouvé une autre parade : avant de filtrer sur onFilterRecord, rajouté

    tbFacture.Filter:='';


    Je n'avais pas donné rapidement cette info.

    Cependant ta formule est plus élégante.

    Merci

    Problème résolu

  11. #11
    Membre régulier
    Inscrit en
    Avril 2008
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 167
    Points : 89
    Points
    89
    Par défaut Filtrer une table en comparant deux champs entre eux
    re
    j'ai testé la formule que tu préconises:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure TForm1.tbFactureFilterRecord(DataSet: TDataSet;
      var Accept: Boolean);
    begin
      if DataSet.Filter <> '' then
        Accept := True
      else
        Accept := FieldByName('MontantVerse').AsCurrency < FieldByName('MontantTTC').AsCurrency;
    end;
    A la compilation j'ai le message suivant :
    [Erreur] Uprincipal.pas(2079): Identificateur non déclaré : 'FieldByName'

    Par Contre avec la formule d'une variable booleene supplémentaire NonSolde que je fixe à True (pout tester sur OnFilterRecord) et faux avec tbFacture.Filter;='' (pour tester sur la propriété Filter) ça marche à merveille.
    soit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    procedure TForm1.tbFactureFilterRecord(DataSet: TDataSet;
      var Accept: Boolean);
     begin
        If NonSolde then
        begin
          with DataSet do
          Accept := FieldByName('MontantVerse').AsCurrency < 
                        FieldByName  'MontantTTC').AsCurrency;
         end;
    end;
    merci.

  12. #12
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Citation Envoyé par damene Voir le message
    A la compilation j'ai le message suivant :
    [Erreur] Uprincipal.pas(2079): Identificateur non déclaré : 'FieldByName'
    A oui effectivement, j'ai commis une petite erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TForm1.tbFactureFilterRecord(DataSet: TDataSet;
      var Accept: Boolean);
    begin
      with DataSet do
      begin
        if Filter <> '' then
          Accept := True
        else
          Accept := FieldByName('MontantVerse').AsCurrency < FieldByName('MontantTTC').AsCurrency;
      end;
    end;
    Mais si ta méthode fonctionne, tant mieux.

    @+ Claudius

  13. #13
    Membre régulier
    Inscrit en
    Avril 2008
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 167
    Points : 89
    Points
    89
    Par défaut Filtrer une table en comparant deux champs entre eux
    C'est parfait.
    ça marche très bien.
    Je préfère ta solution car j'ai une variable en moins à gérer.
    Merci.

  14. #14
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Citation Envoyé par damene Voir le message
    Merci.

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 10/09/2014, 16h04
  2. Réponses: 6
    Dernier message: 18/06/2014, 16h13
  3. Réponses: 3
    Dernier message: 15/02/2011, 14h55
  4. Filtrer une table sur deux de ses champs
    Par damene dans le forum Débuter
    Réponses: 2
    Dernier message: 02/03/2009, 10h09
  5. Réponses: 5
    Dernier message: 06/06/2006, 14h12

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