formateur informatique

Corriger le défaut des listes liées en VBA Access

Accueil  >  Bureautique  >  Access  >  Access VBA  >  Corriger le défaut des listes liées en VBA Access
Livres à télécharger


Pour partager cette vidéo sur les réseaux sociaux, voici son url absolue :

Pour l'intégrer sur votre site internet ou blog, vous pouvez l'embarquer :

Sujets et formations similaires :


Corriger le défaut des listes liées

Dans cette formation VBA Access, nous livrons une solution intéressante pour corriger un défaut concernant les listes déroulantes liées entre elles. Nous avions développé un formulaire Access pour synthétiser et relier les données. Et sur ce formulaire, nous avions fait interagir deux listes déroulantes, grâce à une requête au critère dynamique. Le choix dans la liste parent restreint naturellement les possibilités dans la liste enfant.

Cependant, la valeur précédente dans la liste enfant est conservée en mémoire, malgré le changement dans la liste parent. Elle reste proposée bien qu'elle n'appartienne plus aux choix offerts. Ce défaut est à la fois déroutant et dangereux. En effet, cette donnée peut très bien être enregistrée dans la base de données, bien qu'incohérente.

Défaut de liaison entre listes déroulantes reliées sur formulaire Access



Dans l'extrait de la capture ci-dessus, le modèle de la marque Renault reste proposé parmi les modèles de la marque Peugeot.

Nous avions d'ailleurs noté le même souci au travers de la formation Excel pour relier des listes déroulantes par calculs. Mais dans l'un et l'autre cas, l'objectif était d'apporter la solution pour des listes en cascade sans l'appui du code VBA. Et nous y étions parvenus.

Sources et présentation de la problématique
Pour apporter cette correction, nous proposons de récupérer la petite base de données Access reliant ces listes déroulantes. Après un téléchargement, ce fichier est considéré comme inconnu. Il s'agit d'une mesure de précaution de la part des logiciels de la gamme Office.
  • Dans le volet des objets Access sur la gauche, double cliquer sur la table Parc,
Nous affichons ainsi son contenu en mode feuille de données. Comme vous le constatez, l'entreprise gère un parc d'automobiles d'occasion en transit.

Table de base de données Access gérant des véhicules en occasion

Maintenant que les présentations sont faites, nous souhaitons vérifier le fonctionnement des listes déroulantes.
  • Fermer la table Parc en cliquant sur la croix de son onglet,
  • Dans le volet des objets Access sur la gauche de l'écran, double cliquer sur le formulaire Parc,
Nous commandons ainsi son exécution. Comme vous le remarquez, le gestionnaire peut visionner les véhicules indépendamment et les modifier. Un changement de Marque dans la première liste déroulante, impose un changement de contenu dans la seconde liste, celle des modèles. Ce fonctionnement est tout à fait logique. Ces deux listes déroulantes sont donc bien reliées entre elles.
  • Dans la première liste déroulante, choisir la marque VOLKSWAGEN à la place de Renault,
  • Dans la foulée, déployer la liste enfant des modèles,
Défaut de liaison des listes déroulantes sur formulaire Access à cause du choix précédent conservé

Comme vous le remarquez, deux modèles appartenant à la marque Volkswagen sont effectivement proposés. La seconde liste déroulante s'est remplie en fonction du choix émis dans la première liste. Cependant, et cela ne vous a sans doute pas échappé, le modèle précédemment sélectionné est toujours proposé. Et ce modèle (Modus) appartient à la marque Renault et non Volkswagen. Sur la capture d'écran, il s'agit du modèle 207 SW. Des manipulations supplémentaires ont été réalisées. Les symptômes sont cependant bien les mêmes.

Comme nous le disions en préambule, il ne s'agit pas d'un défaut de liaison entre les listes déroulantes mais du fonctionnement normal. Le précédent choix est conservé en mémoire.

Et malheureusement, si nous changions d'enregistrement, ce choix incohérent serait sauvegardé. Est-il nécessaire de le rappeler, une base de données écrit en temps réel sur le disque dur.



Listes liées sans code VBA
Pour pallier ce souci dans la liaison, nous proposons d'accéder aux requêtes qui établissent la relation. Nous comprendrons mieux comment le corriger.
  • Dans le ruban Accueil, cliquer sur la flèche du bouton Affichage,
  • Dans la liste, choisir Mode création pour accéder au formulaire en conception,
  • Cliquer sur la première liste déroulante pour la sélectionner,
  • Dans le ruban Création, cliquer sur le bouton Feuille de propriétés s'il elle n'est pas visible,
En consultant sa feuille de propriétés, nous constatons que cette liste déroulante se nomme Marque.
  • Activer l'onglet Données de cette feuille,
Comme l'indique la propriété Contenu, la source de cette liste est la requête nommée R_Marques.
  • Double cliquer sur son nom dans le volet des objets Access sur la gauche de l'écran,
Ainsi nous l'exécutons. Nous constatons qu'elle liste en effet les marques de façon unique.
  • Dans le ruban Accueil, cliquer sur la flèche du bouton Affichage,
  • Dans la liste, choisir Mode SQL,
Nous remarquons la présence d'une clause Distinct dans sa syntaxe. Nous l'avions mise en oeuvre pour éliminer les doublons :

SELECT DISTINCT Marque FROM Parc;
  • Fermer cette requête en cliquant sur la croix de son onglet,
  • De retour sur le formulaire en conception, sélectionner la seconde liste déroulante,
Elle se nomme donc Modèle et sa source est la requête R_Modeles comme l'indique la propriété Contenu dans l'onglet Données de sa feuille de propriétés.
  • Dans le volet des objets Access, double cliquer sur son nom pour l'exécuter,
Et comme vous le remarquez, elle n'affiche rien. Ce phénomène est tout à fait logique. Il s'agit d'une requête dynamique. Elle attend le choix émis dans la première liste déroulante, celle des marques, pour effectuer la sélection et remplir son contenu en conséquence.
  • Dans le ruban Accueil, cliquer sur la flèche du bouton Affichage puis choisir le mode Création,
Et comme vous le constatez, la sélection des modèles pour le champ conservé visible dans la grille de requête, dépend du choix de la marque effectué depuis la liste déroulante Marque sur le formulaire.

Requête Access dynamique pour relier des listes déroulantes sur un formulaire

Cette liaison est donc très intéressante et fonctionnelle. C'est elle qui articule les listes déroulantes. Désormais, la question est : Comment corriger ce problème de valeur mémorisée, au changement dans la liste parent ?



Contrôler la liaison des listes par le code VBA
Ce sont quelques très simples instructions Visual Basic qui vont permettre de corriger le défaut.
  • Fermer la requête R_Modeles en cliquant sur la croix de son onglet,
  • Sur le formulaire, sélectionner de nouveau la liste déroulante parent nommée Marque,
  • Puis, activer l'onglet Evènement de sa feuille de propriétés,
Nous remarquons qu'une macro est associée à son évènement Sur changement. En effet, elle a pour objectif d'imposer le recalcul pour que la liste déroulante enfant se charge en conséquence. C'est l'astuce intéressante que nous avions mise en oeuvre pour contourner VBA. Nous proposons de le constater.
  • Cliquer sur le petit bouton situé sur la droite de la ligne de l'évènement,
Macro Access pour actualiser liaison de remplissage des listes déroulantes en cascade sur le formulaire

Nous basculons ainsi dans l'éditeur de macros Access. Et comme vous le voyez, l'astuce est triviale. Nous nous sommes contentés de choisir l'action ActualiserEnregistrement. Comme cette opération se déclenche au changement détecté dans la première liste déroulante, le contenu de la seconde s'actualise automatiquement. Mais aucune action de macro ne permet de préciser que nous ne souhaitons pas conserver la précédente valeur mémorisée.

Nous allons donc remplacer cette macro par un code VBA Access. Lui aussi doit se déclencher sur évènement, cela va de soi.
  • Fermer l'éditeur de macros,
  • De retour sur le formulaire Access, supprimer la macro incorporée associée à son évènement Sur changement, depuis sa feuille de propriétés,
  • Puis, cliquer de nouveau sur le bouton situé en regard,
  • Dans la boîte de dialogue, choisir Générateur de code,
De fait, et comme nous l'avons appris au travers des formations VBA Access, nous basculons dans l'éditeur de code VBA, entre les bornes de la procédure évènementielle Marque_Change. Les instructions que nous y ajouterons se déclencheront au changement de valeur détecté dans la liste parent.

Deux lignes suffisent. Il s'agit d'effacer la valeur sélectionnée dans la liste Modèle puis d'imposer l'actualisation des enregistrements pour établir la liaison avec la liste parent.
  • Ajouter les instructions VBA suivantes :
Private Sub Marque_Change()

Modèle.Value = ''
Modèle.Requery


End Sub


Tout d'abord, la propriété value du contrôle de liste déroulante Modèle permet d'accéder à son contenu. Nous l'affectons sur une chaîne vide. Ainsi, nous effaçons cette fameuse proposition mémorisée et dangereuse. Puis, nous exploitons sa méthode Requery pour imposer le recalcul, en l'occurrence ici l'actualisation des enregistrements. L'objectif est que le contenu de cette liste enfant réagisse en fonction du choix dans la liste parent, pour se remplir en conséquence, comme l'impose la requête dynamique qui est définie en source de données.

Remarque : l'emploi des accents n'est jamais judicieux en programmation. Nous aurions dû nommer cette liste : Modele. Mais jusqu'alors cette application ne faisait pas appel au code VBA.
  • Enregistrer les modifications (CTRL + S) et revenir sur le formulaire,
  • L'exécuter en enfonçant la touche F5 du clavier,
  • Changer de marque à l'aide de la première liste déroulante,
Cette fois en effet, nous constatons que la proposition précédente n'est plus suggérée. Seuls les modèles correspondant à la marque choisie dans la liste parente sont disponibles. C'est ce qu'illustre la capture ci-dessous.

Corriger défaut de valeur mémorisée dans choix de liste déroulante sur formulaire grâce au code VBA Access

En revanche, un problème surprenant subsiste.

Si nous changeons d'enregistrement, ce ne sont pas les modèles de la marque active qui sont proposés dans la liste déroulante enfant. Il s'agit des modèles de la précédente marque, celle de l'enregistrement précédent. Access considère qu'aucun changement n'a été opéré dans la liste déroulante parente. En conséquence, il ne réactualise par le contenu de la liste enfant. Pour pallier le problème, nous devons forcer l'actualisation, une fois encore, par le code VBA.

Un changement d'enregistrement a pour effet d'activer le formulaire, de lui rendre le focus. Nous devons gérer cet évènement.
  • Revenir sur le formulaire en mode conception,
  • Le sélectionner par son angle supérieur gauche (Cf. capture ci-dessous),
Sélectionner le formulaire Access complet pour régler ses propriétés
  • Puis, dans l'onglet Evènement de sa feuille de propriétés, cliquer sur le petit bouton de son évènement Sur activation,
  • Dans la boîte de dialogue qui suit, choisir Générateur de code,
Nous basculons de nouveau dans l'éditeur VBA Access mais cette fois, entre les bornes de la procédure évènementielle Form_Current. En d'autres termes, son code se déclenchera à chaque activation du formulaire, donc à chaque changement d'enregistrement notamment.
  • Ajouter les deux instructions VBA suivantes :
Private Sub Form_Current()

Marque.Requery
Modèle.Requery


End Sub


Grâce à la méthode Requery des objets de liste déroulante, nous forçons l'actualisation des enregistrements qui leur sont liés. Il s'agit bien sûr des requêtes source respectives.
  • Enregistrer les modifications et basculer sur le formulaire,
  • Enfoncer la touche F5 pour l'exécuter,
Le changement dans la liste parent a toujours pour effet d'annuler la précédente valeur suggérée. Et nous pouvons associer un nouveau modèle correspondant à la nouvelle marque. Mais cette fois, en plus de cela, lorsque nous changeons d'enregistrement, la liste enfant est correctement chargée des modèles de la marque présélectionnée dans la liste parent.

Nous avons donc parfaitement réussi la liaison entre les listes déroulantes du formulaire Access tout en corrigeant ce petit défaut contraignant.

 
Sur Facebook
Sur G+
Sur Youtube
Les livres
Contact
Mentions légales



Partager la formation
Partager sur Facebook
Partager sur Google+
Partager sur Twitter
Partager sur LinkedIn