Tutoriel réalisé avec Access 2016
Dans ce tutoriel, nous allons revoir comment créer des listes en cascade avec Access.
Dans un précédent article, je vous ai montré comment créer une zone de liste en cascade avec Access qui d’ailleurs contenait une petite erreur dans le titre, car il s’agissait plutôt d’une liste déroulante en cascade et non pas d’une zone de liste. Malheureusement, suite à ce tutoriel, quelques abonnés m’avaient fait remarquer que les données issues de la seconde liste ne restaient pas affichées dans les autres enregistrements si le filtre de la première liste de l’enregistrement en cours n’était pas le même. C’est-à-dire que si je choisis la France en tant que Pays, puis Paris, qu’ensuite, dans un autre enregistrement, je choisis le Portugal avec Porto et que je reviens sur l’enregistrement avec la France, Paris avait disparu. Heureusement, dans la table, les données étaient bien présentes, mais on saisit et consulte les données dans un formulaire et non dans une table. Voici donc un petit supplément au tutoriel précédent dont la solution m’a été gentiment transmise par Olivier (un commentateur du blog) et que j’ai pu tester à 2 reprises pour des clients.
Nous allons partir de la base de données qui résulte du précédent tutoriel avec les sources de données des 2 listes et le code VBA. Si vous n’avez pas suivi le précédent tutoriel sur la création de zone de liste en cascade, je vous invite à le lire et vous trouverez, au bas de l’article, la base de données utilisée dans le tutoriel qui suit.
Nous n’allons pas toucher aux contenus des 2 listes du formulaire F_Prise_de_RDV, mais simplement créer 2 requêtes et y faire référence en VBA. En fait, le souci de cette « perte d’information » réside dans le fait que la source de la seconde liste est basée sur un critère (le Pays), or, si je change de pays, le critère filtre selon l’enregistrement en cours (si vous changez d’enregistrement et que celui-ci possède déjà un Pays différent du dernier que vous avez sélectionné et que vous cliquez sur la liste des villes, vous verrez que les villes ne correspondront pas au pays concerné par l’enregistrement). Nous allons donc programmer pour faire en sorte de ne pas prendre ce critère en compte sauf quand cela est nécessaire.
SOMMAIRE
Création de la requête filtrée
La première requête est la même que celle que nous utilisons pour le contenu. Donc vous avez 2 méthodes possibles pour la créer :
- Soit la créer de toutes pièces en allant dans l’onglet Créer > Création de requête
. Vous sélectionnez la table T_villes, vous sélectionnez les champs ID, Ville (que vous triez par ordre Croissant) et ID_Pays avec comme critère
[Formulaires]![F_Prise_de_RDV]![RDV_Pays]
- Soit vous ouvrez le contenu de la liste déroulante des villes dans le formulaire F_Prise_de_RDV et vous cliquez droit sur l’onglet > Mode SQL
. Vous copiez le code en entier et refermez le formulaire entièrement sans enregistrer de modification. Puis vous créez une requête comme indiqué précédemment, mais sans ajouter de table, vous repassez en Mode SQL
par un clic droit sur l’onglet et vous remplacez le SELECT par ce que vous avez copié auparavant. Ici, il n’y a que 3 champs, mais si vous avez besoin de requête assez longue et que vous ne pouvez pas la dupliquer comme nous allons le faire après, cela peut être très utile pour gagner du temps.
Une fois l’une ou l’autre des étapes effectuées, fermez la requête en l’enregistrant sous le nom R_Villes_filtre. Le nom n’a pas d’importance, mais on y fera référence en VBA.
Création de la requête non filtrée
Pour la requête filtrée, cela va être encore plus simple : copiez-collez la requête que nous venons de créer (Ctrl + C et Ctrl + V dans le panneau latéral) et donnez-lui le nom de R_Villes. Ouvrez‑la en Mode création et supprimez le champ ID_Pays avant de la fermer en l’enregistrant.
Saisie du code VBA pour la liste en cascade
Nous allons maintenant pouvoir faire référence à ces requêtes. Ouvrez le formulaire F_Prise_de_RDV en Mode création et cliquez sur la liste déroulante des villes. Dans la Feuille de propriétés
, à l’onglet Évènement, cliquez sur les 3 points de la ligne Sur réception focus, puis appelez le Générateur de code. Comme nous voulons que la liste soit filtrée lorsque le focus est récupéré pour cette liste, nous allons utiliser la requête filtrée. Saisissez le code :
Me.RDV_Villes.RowSource = "R_Villes_filtre"
Si vos noms sont différents, adaptez-les en sachant que RDV_Villes correspond à la liste déroulante et R_Villes_filtre à la requête filtrée.
Fermez la fenêtre VBA et cliquez sur la ligne d’évènement Sur perte focus où, toujours avec le Générateur de code, nous allons faire référence à la requête non filtrée :
Me.RDV_Villes.RowSource = "R_Villes"
Voici le code complet du formulaire avec le code déjà présent :
Option Compare Database
Private Sub RDV_Pays_Change()
Me.RDV_Villes.Requery
End Sub
Private Sub RDV_Villes_GotFocus()
Me.RDV_Villes.RowSource = "Rqt_villes_filtre"
End Sub
Private Sub RDV_Villes_LostFocus()
Me.RDV_Villes.RowSource = "Rqt_villes"
End Sub
Vous pouvez maintenant fermer la fenêtre VBA ainsi que le formulaire en l’enregistrant et utiliser votre formulaire avec toutes les données visibles.
Bonjour,
Merci pour ce tuto clair.
Je suis à la recherche d’une solution pour réussir à intégrer une liste déroulante dans un formulaire en mode feuille de donnée.
Je m’explique.
J’ai 2 tables :
tProduit (IDProduit, description, type de conditionnement)
–> liste de tous nos produits :
1 résistance 100 ohm
2 condensateur type A
tLot (IDProduit, SN, quantité courante)
–> liste de tous les lots, chaque lot ayant son propre N° de série :
1 AAAA
1 AAAB
1 AAAC
2 XXXX
2 XXXY
Dans cette feuille de données, j’ai 3 colonnes :
– IDProduit
– N° série
– Quantité
Je voudrais que la liste déroulante proposée pour N° série réussisse à filtrer selon le IDProduit de la ligne en cours de modification.
Ainsi, lorsque je sélectionne le SN d’une ligne dont le produit est 2 (condensateur), j’aimerais ne voir apparaître que les SN (XXXX et XXXY).
Je rappelle que je veux le faire dans un formulaire en mode feuille de données.
Est-ce possible et, si oui, comment ?
Merci.
Bonjour Elen,
Vous avez essayé le tutoriel ? Car en passant mon formulaire en mode feuilles de données, ça fonctionne toujours.
Ça marche presque en effet, car en mode feuille de données, si vous éditez la colonne ville un enregistrement après l’autre, vous verrez que les sélections s’effacent au fur et à mesure.
J’ai l’impression que l’event lost focus n’est pas généré si l’on reste sur la même colonne.
Y a-t-il moyen que ça marche à tous les coups ?
Merci.
C’était le cas avec la première version du tutoriel, mais plus avec celui-ci (je viens encore d’essayer).
Si l’évènement Lost focus n’est pas utilisé, c’est qu’il n’y pas « Procédure évènementielle » sur la ligne de l’évènement ou que le code VBA n’a pas été créé.
Salut Lydia. Merci pour ces tutoriels. Je bute sur un niveau : mes listes en cascade fonctionnent à merveille. J’ai suivi votre deuxième tutoriel pour « forcer » les enregistrements à rester. Au niveau de la création de la requête avec filtre, j’ai exécuté toutes les étapes que vous avez données. Mais quand il est temps d’exécuter la requête, apparaît un message d’erreur (Entrer une valeur de paramètre : Formulaire!F_ENTREES.GROUPE). Je vois que mon critère n’est pas reconnu. Voici le code en mode SQL de ma requête avec filtre :
SELECT DETAIL_ENTREE.ID, DETAIL_ENTREE.ENTREE
FROM DETAIL_ENTREE
WHERE (((DETAIL_ENTREE.ID_AGREGAT_ENTREE)=[Forms]![F_ENTREES].[GROUPE]));
Merci d’avance pour votre attention et votre temps.
Bonjour Fodé,
Votre formulaire était-il ouvert à ce moment-là (et pas en mode création) ? Le champ sur lequel porte le critère est-il présent dans le formulaire ?
Bonjour, je reprends encore votre exemple. J’ai une base de données avec une liste de métiers à restreindre en fonction d’une liste de catégories.
J’ai un formulaire que j’arrive à faire fonctionner comme dans votre exemple, mais je voulais le reprendra afin de bien comprendre avant de l’implanter dans une base de données plus complexe alors j’ai créé un nouveau formulaire (toujours dans cette base de données). J’ai également dupliqué la requête filtre afin que le critère corresponde avec ce 2ème formulaire.
Cela ne fonctionne plus. Est-ce possible de vous envoyer la base de données par courriel pour que vous essayiez de voir ce qui ne fonctionne pas ?
Le problème est que dans le 2ème formulaire, les métiers sélectionnés s’effacent parfois comme si la requête filtre était toujours appliquée.
Merci pour votre aide.
Edit :
Je me donne moi-même un élément de réponse. Si je fais l’exercice en créant un formulaire à l’aide de l’assistant. L’affichage mode feuille de donnée ne fonctionne pas correctement alors qu’en mode formulaire, on a le comportement souhaité.
En créant le formulaire à partir de l’option Plus de formulaire > Feuille de données et en appliquant les 3 évènements correctement, l’affichage se fait correctement en mode feuille de données.
Avez-vous une idée de ce qui se passe ?
Merci.
Bonjour Elen.
Je vous envoie un e-mail pour que vous puissiez envoyer la BDD.
Bonjour,
J’ai bien suivi le tuto. La cascade fonctionne bien, mais lorsque je veux sélectionner un élément dans le deuxième niveau (équivalent « villes » dans votre tuto), les éléments affichés sont les ID_Pays (qui sont les mêmes, donc le filtre fonctionne). Lorsque je clique un proposé « ID_Pays », il affiche ensuite la ville dans l’encadré. Je ne comprends pas.
Bonjour,
Vous avez dû inverser les sources.
Bonjour Lydia,
Merci de ces tutos, c’est vraiment très utile !
J’ai plus ou moins le même problème que Fodé.
J’ai fait les 2 tutos et tout marche à merveille…seulement, dès que je ferme le formulaire et l’ouvre à nouveau, il m’affiche un message d’erreur :
« Entrer une valeur de paramètre : [Formulaires]![F_Prise_de_RDV] »
Je suis obligée de retourner dans la version création et de revalider les procédures événementielles (sans changer quoi que ce soit) pour que les villes chargent.
Auriez-vous une idée du problème ?
Merci de votre réponse.
Bonjour Marianne,
Pouvez-vous répondre aux questions posées à Fodé ? Si vous lancez la requête filtrée avec le formulaire ouvert et un pays choisi, le message persiste-t-il ?
Merci de votre réponse. Je vais essayer de m’expliquer…
Quand je fais les changements dans le formulaire en mode création comme dans les tutos, une fois enregistré, tout fonctionne et je peux modifier mes données sans problème.
Si je ferme le formulaire et/ou la base de données, le message apparaît au moment de l’ouverture du formulaire en mode saisie.
Une fenêtre s’ouvre et me demande d’entrer une valeur paramètre. Si je ne retourne pas dans la partie création et souhaite changer le pays, un autre message m’indique :
« l’expression sur le changement entrée comme paramètre de type événement est à l’origine d’une erreur. Return sans GoSub »
J’espère que cela vous parle plus qu’à moi 😉
Essayez de faire la manipulation indiquée par helas.
Ça marche !!!
Merci infiniment. C’est passionnant Access, mais quand on fait ça en autodidacte, c’est parfois un casse-tête.
Merci bien Lydia.
Bonjour Lydia,
J’ai suivi toutes les étapes des 2 tutoriels « comment créer des listes en cascade avec Access ». J’ai donc suivi le deuxième tutoriel pour « forcer » les enregistrements à rester. J’ai exécuté toutes les étapes, mais lorsque je visualise mes fiches les données sont absentes jusqu’à ce que je crée une nouvelle fiche et alors tout s’arrange ? (j’ai utilisé les mêmes noms de champ et la même structure que votre exemple pour m’assurer du bon fonctionnement, mais il y a tout de même un « bug »).
Bonjour Robert,
Est-ce que les mots « [Procédure évènementielle] » apparaissent bien sur les lignes de tous les évènements, dans l’onglet Évènement, qui sont écrits dans le code ? Car un autre abonné avait le même problème et c’est un des évènements qui n’était pas « appelé ».
Bonjour,
À la feuille de propriétés, pour le champ « RDV_Pays », {Procédure événementielle} apparaît à la ligne « Sur changement »
À la feuille de propriétés, pour le champ « RDV_Villes », {Procédure événementielle} apparaît aux lignes « Sur réception focus » et « Sur perte focus ».
Bonjour,
Et est-ce que la source du champ RDV_Villes est la requête R_Villes ?
Bonjour,
Je ne sais pas si cela répondra bien à votre question, mais, à la feuille de propriétés de mon formulaire « F_Prise_de_RDV », pour le champ « RDV_Villes », à l’onglet Données, Origine source est bien « Table/Requête » et Source contrôle est « RDV_Villes »…
Bonjour,
Et entre ces 2 lignes, quel est le contenu ?
Réponse :
SELECT T_Villes.ID, T_Villes.Ville FROM T_Villes WHERE T_Villes.ID_Pays = Forms!F_Prise_de_RDV.RDV_Pays;
Cela doit être la syntaxe de la requête filtrée, or, c’est le nom de la requête non filtrée qui doit être sur la ligne Contenu.
Désolé.
J’ai de la difficulté à suivre…
Bonjour,
Merci pour ce tuto bien utile 🙂
Est-il possible de créer des listes en cascades si la première liste permet des choix multiples ?
Par exemple, il serait possible de sélectionner France et Portugal (pour reprendre votre exemple), et j’aimerai donc afficher dans la liste suivante la liste des villes françaises et portugaises. Cela est-il envisageable ?
Bonjour Téa,
À l’heure actuelle, je ne vois pas comment procéder sachant que les pays sélectionnés se retrouvent à la suite, séparés par des points-virgules.
Bonjour Lydia,
Merci pour cette réponse.
Est-ce qu’il est possible, du coup, de laisser la liste déroulante complète et de mettre un message d’erreur ou un filtre si la ville ne correspond pas aux pays sélectionnés ?
Bonjour Téa,
La ville est filtrée par le pays, je ne vois pas pourquoi il y aurait besoin d’un message d’erreur, puisqu’il faudra bien saisir un pays.
Bonjour Lydia,
Merci pour ce tutoriel, mais j’observe le phénomène suivant :
Lorsque j’ajoute aux tables un nouveau pays et/ou une nouvelle ville, dans le formulaire Prise de RDV, je retrouve bien les nouveaux choix, mais les nouvelles entrées ne se placent pas en ordre alphabétique ?
Bonjour Robert,
Avez-vous trié par ordre croissant les champs dans les requêtes ?
Bonjour Lydia,
Bon début d’année.
Oui, dans la table pays et dans la table villes, j’ai trié les champs villes et pays par ordre alphabétique.
Si la manipulation est à faire directement dans une des requêtes de votre exemple de liste en cascade, alors j’ignore comment le faire…
Merci.
Très bonne année également.
C’est dans les requêtes créées, en Mode création.
Salut Lydia,
J’ai continué à bidouiller dans ma base de données et j’ai trouvé comment faire le tri du champ ville dans la requête…
Merci encore…
Bonjour Lydia,
Je travaille sur une nouvelle version plus aboutie de ma BDD.
Pour le moment, j’ai un niveau de cascade. Mais, afin d’accélérer les saisies et surtout éviter les erreurs, je souhaite faire des listes en cascade à plusieurs niveaux.
Je m’explique en prenant en analogie des tables de votre tuto.
Nous avons les villes qui dépendent des pays. Mais si on veut une rue qui dépend de quartier, qui dépend de ville, qui dépend de pays, on procède de la même façon en partant de la cascade mère pour arriver à la dernière ?
J’ai tenté le coup dans la BDD test, mais je n’arrive pas à grand-chose.
Merci pour l’aide.
ND
Bonjour Nathalie,
Avez-vous essayé de mettre le filtre de la première liste, puis de la 2e sur une même ligne de critère dans la requête pour filtrer la 3e liste ?
Coucou Lydia,
Non, je n’ai pas encore essayé (d’ailleurs, je ne suis pas certaine de bien comprendre la manœuvre). Je vais déjà reprendre dans un premier temps les 2 tutos sur les listes en cascade pour me remettre dedans, car, après un essai de ce second tuto, je n’arrive pas au résultat attendu.
Ensuite, j’essaierai de rajouter cascade après cascade en appliquant la même procédure en croisant les doigts.
En tout cas mille mercis pour ces tutos !!!!!
Re,
Alors, pour le moment, en me limitant à une cascade, j’ai un problème qui ressemble à celui rencontré par Robert (mon formulaire étant en feuille de données, cela saute aux yeux). J’enregistre mes données et tout va bien. Je ferme et rouvre mon formulaire, les données de la liste héritée (la liste fille donc) ont disparu sauf celles de ma dernière entrée mère. Par exemple, je tape des pays avec des filles et, comme dernier pays, je rentre France, et bien si je ferme, puis que j’ouvre à nouveau le formulaire toutes les autres villes que celles de France ont disparu. Si je tape un autre pays, toutes les données avec les villes du pays en question réapparaissent.
J’ai beau avoir fait et refait…toujours pareil.
Merci Lydia.
Bonjour à nouveau Lydia,
Je tâtonne et j’avance très doucement! J’ai (je crois) réussi à créer une cascade à double niveau (pays, ville, quartier) !!! Mais, rien à faire, certaines données disparaissent quand je modifie l’entrée dont elle dépend (le pays reste, les villes disparaissent et les quartiers restent). Je n’arrive décidément pas à régler ce problème. Est-il possible de vous contacter par e-mail afin de ne pas trop polluer ce post ?
Bonjour Nathalie,
Ça ne pollue pas du tout le post, puisque c’est la raison pour laquelle j’ai créé ce tutoriel : la cascade fonctionnait, mais les données disparaissaient dans le précédent article.
Avez-vous également créé les évènements dans le code VBA en les adaptant à la cascade en question ?
Hello Lydia,
Oui, j’ai bien créé les requêtes avec le VBA. Depuis que je me suis inscrite, j’ai récupéré la BDD du tuto. En faisant un nouveau Formulaire (en feuille de données) et en reprenant les tutos, cela fonctionne. Je ne m’explique pas pourquoi ça ne fonctionne pas sur ma BDD. C’est très frustrant, car je sais que je ne suis pas loin ! Je me suis rendu compte qu’en faisant F5 les données réapparaissaient. Du coup, j’ai tenté de rajouter un Me.Refresh sur Activation, puis sur Ouverture…bref j’ai tenté ce genre d’action, mais rien n’y fait.
Merci pour l’aide.
Bonjour Nathalie,
Je vous envoie un e-mail.
Hello Lydia,
Réponses envoyées !!!
Un grand merci.
Bonjour,
J’ai tout essayé pour créer des listes en cascades, mais je n’y arrive pas.
Je voulais savoir si vous pouvez m’apporter un peu d’aide.
Merci d’avance.
Jonathan
Bonjour Jonathan,
Quel est le souci rencontré ?
Bonjour Lydia,
Avant tout, je vous remercie pour vos tutoriels didactiques et bien conçus.
J’ai suivi pas à pas votre tutoriel (version 1) et la version 2 censée corriger le problème d’effacement des résultats de la liste « villes » à l’affichage.
J’ai repris strictement l’exercice ainsi présenté.
Sauf erreur de ma part (je débute le VBA avec vos tutos), le problème d’effacement à l’affichage n’est pas résolu avec les nouvelles procédures (Sur réception/perte focus).
Pour le reste, tout fonctionne bien…mais cet effacement reste un problème…
Pourriez-vous m’éclairer ? (Confirmez-vous que la mise à jour de juin 2016 a résolu le dysfonctionnement ?)
Je peux vous transmettre ma base « école » (très simplifiée volontairement).
Je vous en remercie par avance.
Cordialement.
Bonjour,
Oui, cela fonctionne, je l’ai même utilisé sur les bases de données de mes clients depuis.
Est-ce que votre formulaire serait en mode Feuille de données ? Il me semble que ça ne fonctionnait pas bien avec ce mode.
Bonjour Lydia,
J’ai un sous-formulaire dans un formulaire, j’ai suivi les instructions dans votre tuto, « sur focus » et « perte focus » et, dans mes enregistrements, sont toujours pareils, si mon produit change, et bien mon sous-produit disparait. Est-ce à cause que c’est un sous-formulaire ? Autrement, ma liste en cascade fonctionne à merveille.
Toujours intéressants tes tutos !
Bonjour Daniel,
Je pense, effectivement, que cela vient du sous-formulaire, car cela a le même effet sur les BDD de certains de mes clients qui utilisent un filtrage dans un sous-formulaire.
Mais la différence avec le tutoriel est de base est que l’information est bien enregistrée dans la table donc pas d’inquiétude à ce niveau (mais vérifiez quand même) 😉
Bonjour Lydia, oui, tout est dans la table.
Hello tout le monde,
Une astuce en VBA que j’ai pu avoir et que je vous partage volontiers, qui permet lors de l’utilisation d’une liste déroulante en cascade, lors de la sélection sur la première liste, de directement ouvrir la seconde liste, de manière à faire son choix sans être obligé de cliquer sur la deuxième liste déroulante.
À mettre dans la liste principale :
Private sub NomListe1_AfterUpdate()
Me![NomListe2].RowSource ="select ChampQuiApparaitDansLaListe2, ChampListe2 from NomDeLaTableConcernee where ChampsListe1=""" & me.NomListe1.column(2) & """ order by ChampListe2;"
Me![NomListe2].setfocus 'Met le focus sur liste 2
Me![NomListe2].DropDown 'Déroule la liste
End sub
J’espère que ce sera clair en explication.
Bonne soirée.
Bonjour et merci Jacques pour l’astuce 🙂