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

Access Discussion :

Filtrer selon un sous-formulaire [AC-2010]


Sujet :

Access

  1. #1
    Membre du Club

    Homme Profil pro
    Retraité
    Inscrit en
    Août 2005
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Août 2005
    Messages : 26
    Points : 47
    Points
    47
    Par défaut Filtrer selon un sous-formulaire
    Bonjour.
    Je rencontre un petit problème qui dépasse mes compétences et que je vais essayer de résumer.
    Dans Access 2010, j’ai une table, que j’appellerai Principale, qui contient donc l’essentiel de l’information, et une autre, disons la Secondaire, qui contient des informations récurrentes qui peuvent s’appliquer à plusieurs des enregistrements principaux. Chaque enregistrement principal peut recevoir plusieurs informations de la table secondaire.
    J’ai donc bâti une relation « plusieurs à plusieurs » au moyen d’une table de jonction intermédiaire.
    J’ai fait un formulaire à partir des informations principales qui contient un sous-formulaire avec les secondaires.
    Tout va bien à ce stade, sauf que je ne peux pas filtrer mes enregistrements principaux en fonction d’une information secondaire : dans VBA, le filtre que je construis ne « voit » pas le champ qui se trouve dans le sous-formulaire.
    J’ai résolu le problème en activant dans Add existing fields : Show all tables, en faisant glisser un champ de la table secondaire sur le formulaire principal (que j’ai pu effacer ensuite, ça ne changeait plus rien [?]). À partir de là le code du formulaire « voyait » le champ du sous-formulaire et je pouvais le filtrer.
    Mais, surprise, le nombre d’enregistrements tel qu’affiché par Access apparaissait multiplié ! En fait, si un enregistrement ne contient qu’une information secondaire, il apparaît normalement ; sinon, Access affiche autant de fois l’enregistrement principal qu’il contient d’informations secondaires associées.
    Connaissez-vous un moyen d’éviter ce phénomène ?
    Autrement dit, comment mettre dans un formulaire des informations provenant d’une autre table et pouvoir filtrer selon elles ?
    Merci d’avance pour votre aide.

  2. #2
    Expert éminent
    Avatar de jimbolion
    Homme Profil pro
    Moulticien
    Inscrit en
    Janvier 2013
    Messages
    3 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Moulticien
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 3 150
    Points : 7 001
    Points
    7 001
    Billets dans le blog
    2
    Par défaut
    Pjouv,

    Je pense qu'un exemple et une copie du modèle n'aurait pas été superflue mais je vais tenter de comprendre et apporter une solution à ton problème sur un exemple personnel dont la problématique ressemblerait à la tienne.

    Imaginons le cas suivant :

    1 table Factures que nous nommerons T_Factures et une table Détails de la facture que nous nommerons (T_DetFactures) avec les informations suivantes :

    T_Factures (IdFacture, NomClient, DateEdition, FactureNo...)
    T_DetFactures(IdDetFacture,IdFacture,ArticleType,Designation,Prix,TVA,Quantite...)

    Effectuer un formulaire père-fils basé uniquement sur la relation IdFacture <-> IdDetFacture ne pose aucune difficulté notoire, et de nombreux sujets traitent de ce problème.

    Ici un schéma de ce que nous pourrions avoir dans nos tables :

    Nom : Capture.JPG
Affichages : 147
Taille : 139,6 Ko

    Dans ton cas, tu souhaiterons donc filtrer les informations sur une information issue de la table T_DetFactures (Table héritée). Nous prendrons par exemple l'ensemble des factures dont le ArticleType correspond à une donnée particulière (Les boulons par exemple)

    Les articles de type boulon (valeur non référencée dans la table d'origine) ne sont pas présents dans toutes les factures mais simplement dans les factures suivantes : 12052, 12053 et 12055.

    En utilisant la relation père-fils basé sur la source control de ta table, tu ne pourras donc pas filtrer les factures qui contiennent uniquement des boulons. Il nous faudra donc changer le recordSource du formulaire en utilisant une requête !

    Tu as donc ceci pour l'instant

    Nom : Capture2.JPG
Affichages : 220
Taille : 83,1 Ko

    Jusque là pas de problèmes particuliers, tu as j'en suis sûr parfaitement suivi mon raisonnement.

    Je vais donc ajouter sur mon formulaire un boite de dialogue permettant de lister l'ensemble des types articles référencés dans ma table détails de facture, et ainsi opérer à la modification du RecordSource. La requête source de données de ma boîte liste permettant in fine de filtrer sera traduite de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT T_DetFactures.ArticleType FROM T_DetFactures GROUP BY T_DetFactures.ArticleType ORDER BY T_DetFactures.ArticleType;
    Dès que l'utilisateur aura sélectionné Boulon dans cette ZonedeListe (ZL_Filtre), nous allons donc (et ce par une requête) filtrer l'ensemble des factures pour lesquelles au moins un des types d'articles comporte une ligne Boulon.

    Voilà ce que donne en mode création l'élaboration de notre liste déroulante : Nom : Capture3.JPG
Affichages : 152
Taille : 86,1 Ko

    Donc sur l'evenement <Apres Mise à Jour> nous allons créer un code VBA grâce au générateur proposé par l'assistant qui contiendra les lignes suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Private Sub ZL_Filtre_AfterUpdate()
    Dim RSql As String
    RSql = "SELECT T_Factures.IdFacture, T_Factures.NomClient, T_Factures.DateEdition, T_Factures.FactureNo " & _
    "FROM T_Factures INNER JOIN T_DetFactures ON T_Factures.IdFacture = T_DetFactures.IdFacture " & _
    "WHERE (((T_DetFactures.ArticleType)='" & Nz(Me.ZL_Filtre, "") & "'));"
    Me.RecordSource = RSql
    '
    Me.Refresh
    End Sub
    NB : La boîte liste retournant une chaîne de type texte, le champ issu du formulaire a été protégé par des simples quotes : ='" & Nz(Me.ZL_Filtre, "") & "'));"

    La chaîne Rsql nous permet donc de modifer la source du formulaire et nous mettons à jour la propriété RecordSource de notre formulaire principal (Me.RecordSource = RSql). Le me.Refresh permet de rafraîchir l'actualisation des données.

    Dans l'exemple suivant, le sélecteur d'enregistrements nous retourne bien 3 (qui correspond aux trois factures sus-citées sur notre exemple).

    Nom : Capture4.JPG
Affichages : 122
Taille : 52,6 Ko

    Je joins un zip de l'exemple au format Access 2000, afin que toi ou d'autres puissent bénéficier de cette réponse.

    L'exemple est disponible ici : Factures.zip

    J'espère qu'avec cela, tu seras capable d'adapter ta demande et enfin réaliser ce fameux filtre.

    JimBoLion

  3. #3
    Membre du Club

    Homme Profil pro
    Retraité
    Inscrit en
    Août 2005
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Août 2005
    Messages : 26
    Points : 47
    Points
    47
    Par défaut Relations « plusieurs à plusieurs »
    Bonjour.
    Merci infiniment de m’avoir répondu de façon détaillée.
    Mais, après avoir beaucoup transpiré en vain pour reproduire ton code sur une base test, je viens de comprendre (enfin !) pourquoi je n’y arrivais pas.
    Les relations dans ta base sont de type « 1 à plusieurs », et ta table T_DetFactures contient donc un grand nombre de doublons (du moins quand elle grossira). Je sais que c’est la bonne façon pour faire une facturation, mais … je ne fais pas une facturation. :-)
    C’est pour cela que j’avais construit des relations « plusieurs à plusieurs » : à la fois une facture pointe vers plusieurs articles ; et un article est appelé par plusieurs factures.
    Je te renvoie ta base modifiée à mon idée (dans cette version, il n’y a plus qu’un enregistrement par article).
    Cf. le nouveau formulaire « F_Factures_Nouveau ».
    La question reste donc : comment sur ce formulaire filtrer pour ne voir que les factures contenant des boulons par exemple – et, accessoirement, comment annuler le filtre pour retrouver l’ensemble des enregistrements (et donc sans qu’ils soient dédoublés).
    Merci encore de ton attention.
    Bon dimanche.
    Pjouv
    Fichiers attachés Fichiers attachés

  4. #4
    Expert éminent
    Avatar de jimbolion
    Homme Profil pro
    Moulticien
    Inscrit en
    Janvier 2013
    Messages
    3 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Moulticien
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 3 150
    Points : 7 001
    Points
    7 001
    Billets dans le blog
    2
    Par défaut
    PJouv,

    Les relations dans ta base sont de type « 1 à plusieurs », et ta table T_DetFactures contient donc un grand nombre de doublons (du moins quand elle grossira). Je sais que c’est la bonne façon pour faire une facturation, mais … je ne fais pas une facturation. :-)
    C’est pour cela que j’avais construit des relations « plusieurs à plusieurs » : à la fois une facture pointe vers plusieurs articles ; et un article est appelé par plusieurs factures.
    Ma réponse :

    Je pense qu'un exemple et une copie du modèle n'aurait pas été superflue mais je vais tenter de comprendre et apporter une solution à ton problème sur un exemple personnel dont la problématique ressemblerait à la tienne.
    Nous aurions gagné un échange, mais cela aura permis de comprendre comment cela fonctionne sur un exemple simplifié. Dans la modification que tu m'a envoyé Boulon apparaît donc grâce à ta table de jonction dans 4 factures : 120252, 120253, 120255 et 12056

    Ma réponse évoquée sur le #2 est exactement calqué sur ce principe : le code géré après l’événement ressemble donc à ceci :

    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
    Private Sub ZL_FiltreN_AfterUpdate()
    Dim RSql As String
    Dim filtre As String
    filtre = Nz(Me.ZL_FiltreN, "")
    '
    Select Case filtre
    Case ""
        RSql = "T_Factures"
    Case Else
        RSql = "SELECT T_DetFactures.ArticleType, T_Factures.IdFacture, T_Factures.NomClient, T_Factures.DateEdition, T_Factures.FactureNo " & _
        "FROM T_Factures INNER JOIN (T_DetFactures INNER JOIN T_Jonction ON T_DetFactures.[IdDetFacture] = T_Jonction.[RefDetFactures]) ON T_Factures.[IdFacture] = T_Jonction.[RefFactures] " & _
        "WHERE (((T_DetFactures.ArticleType)='" & filtre & "'));"
    End Select
    '
    Me.RecordSource = RSql
    '
    Me.Refresh
    End Sub
    Cf. Le Formulaire F_Factures_Nouveau_JimBoLion

    La solution ici :

    FacturesModPjouv Jimbolion.zip

    JimBoLion

  5. #5
    Membre du Club

    Homme Profil pro
    Retraité
    Inscrit en
    Août 2005
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Août 2005
    Messages : 26
    Points : 47
    Points
    47
    Par défaut
    Bonjour.
    Désolé pour cette réponse tardive, mais j’ai pris le temps de vérifier que j’arrivais à reproduire votre solution (je ne suis pas familier du SQL), et la réponse est… OUI !
    Merci infiniment, ça fonctionne parfaitement et comme je l’imaginais.
    Je n’avais pas voulu alourdir l’énoncé de ma question dans mon premier message, mais je peux raconter maintenant que je suis en train de me faire une base de données pour mes photos. Je sais qu’il en existe déjà des quantités, mais je voulais pouvoir la paramétrer exactement à mon idée.
    Vu l’aide que j’ai eue sur le site, je ne manquerai pas de la publier sur Developpez quand elle sera terminée de façon à ce que d’autres puissent l’adapter à leur tour.
    Merci encore de votre aide rapide et efficace.
    Pjouv

  6. #6
    Expert éminent
    Avatar de jimbolion
    Homme Profil pro
    Moulticien
    Inscrit en
    Janvier 2013
    Messages
    3 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Moulticien
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 3 150
    Points : 7 001
    Points
    7 001
    Billets dans le blog
    2
    Par défaut
    PJOUV,

    Parfait merci d'avance pour eux

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 28/06/2013, 14h36
  2. [AC-2010] Filtrer un sous formulaire selon une date.
    Par UnessBen dans le forum VBA Access
    Réponses: 1
    Dernier message: 19/07/2012, 22h24
  3. Réponses: 4
    Dernier message: 22/03/2007, 13h43
  4. Réponses: 6
    Dernier message: 16/10/2006, 09h37
  5. Filtrer les éléments d'un sous formulaire
    Par Daniel MOREAU dans le forum Access
    Réponses: 6
    Dernier message: 30/08/2006, 10h43

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