Créer des listes en cascade avec Access (MAJ du tutoriel Créer une zone de liste en cascade avec Access)

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 dans l’Espace Membres 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.

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 Création de requête 2013. 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 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 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 Mode Création 2013 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 Mode Création 2013 et cliquez sur la liste déroulante des villes. Dans la Feuille de propriétés Feuille de propriétés 2013, à 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.

Téléchargez « Créer des listes en cascade avec Access (MAJ du tutoriel Créer une zone de liste en cascade avec Access) » au format PDF

Je vous propose un fichier annexe dans l’Espace Membres contenant la base de données utilisée dans ce tutoriel.

Newsletter

8 commentaires

  1. 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.

  2. Ç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éé.

  3. 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.

  4. 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.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

CAPTCHA
Change the CAPTCHA codeSpeak the CAPTCHA code