Liste à sélection multiple
Comment mettre en place une liste à sélection multiple, et la gérer en Visual Basic ?
Construire la liste
On suppose qu’une table Clients (par exemple) est créée.
- Ouvrez un formulaire en mode Création.
- Si nécessaire, faites apparaître la boîte à outils (par le menu Affichage / Boîte à outils ou l’icône ).
- Vérifiez que l’Assistant Contrôle est activé.
- Cliquez sur l’icône Liste modifiable puis cliquez sur le formulaire.
- Suivez les étapes de l’assistant pour construire votre liste, basée sur la table Clients.
- Une fois la liste terminée, cliquez dessus (le formulaire étant toujours en mode Création) puis faites apparaître ses propriétés en cliquant sur l’icône
- Dans les propriétés de l’onglet Autres, donnez à la propriété
Nom
la valeurlstClients
. - Toujours dans ces propriétés, donnez à la propriété
Sélection multiple
la valeurSimple
(ouEtendu
).
Si vous testez maintenant votre formulaire, il est possible de sélectionner plusieurs clients dans la liste.
Lister les éléments sélectionnés
- Réouvrez le formulaire en mode Création.
- Créez maintenant un bouton de commande (sans assistant).
- Grâce aux propriétés, nommez le bouton
btnListe
. - Dans l’événement
Sur clic
du bouton, tapez le code suivant, qui se charge d’afficher l’un après l’autre les clients sélectionnés (ou un message d’avertissement si aucun client n’a été sélectionné) :
1 2 3 4 5 6 7 8 9 10 11 |
Private Sub btnListe_Click() Dim varI As Variant If Me.lstClients.ItemsSelected.Count = 0 Then MsgBox "Aucun client n'a été sélectionné" Else For Each varI In Me!lstClients.ItemsSelected MsgBox Me!lstClients.ItemData(varI) Next varI End If End Sub |
A vous maintenant d’aménager pour en faire bon usage ! Vous pouvez par exemple vous en servir pour filtrer un formulaire ou un état (voir les commandes OpenForm
ou OpenReport
). Pour plus de détails, consultez bien sûr l’aide d’Access concernant la collection ItemsSelected
et la propriété ItemData
.
Ouvrir un formulaire en fonction de la sélection
Allez, à la demande générale, voici un exemple complémentaire : le listing ci-dessus est aménagé pour ouvrir un formulaire en fonction des clients sélectionnés.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Private Sub btnListe_Click() Dim varI As Variant Dim strFiltre As String strFiltre = "" If Me.lstClients.ItemsSelected.Count = 0 Then MsgBox "Aucun client n'a été sélectionné" Else For Each varI In Me!lstClients.ItemsSelected If strFiltre <> "" Then strFiltre = strFiltre & " OR " strFiltre = strFiltre & "[Numéro Client]='" & _ Me!lstClients.ItemData(varI) & "'" Next varI DoCmd.OpenForm "frm Clients", acNormal, , strFiltre End If End Sub |
Quelques compléments :
- Le formulaire à ouvrir s’appelle frm Clients, le champ sur lequel s’établit le filtre est
[Numéro Client]
. - Les clients sélectionnés sont combinés par un OU (
OR
) : il s’agit d’ouvrir le formulaire en cherchant l’un des clients sélectionnés. Remplacez éventuellement leOR
par unAND
si vous souhaitez cumuler les critères (ici, ça n’aurait aucun sens). - Nous avons supposé que les critères de filtre étaient de type Texte. Si vous filtrez sur un champ numérique, supprimez les apostrophes dans la ligne qui construit le filtre.
bonjour, j’ai testé cette methode, mais quel que soit le nombre d’item que je selectionne cela me renvois tjrs le compte à 0 et la mesbox… de quoi cela pourrait venir?
Est-ce qu’il peut s’agit d’une erreur dans un nom (de champ, d’objet…) ?
Bonjour,
J’ai aussi le même problème. Quelque soit les items sélectionnés, cela m’affiche toujours 0 aussi. Une petite question, pourquoi une listbox à choix multiple n’affiche pas de valeur directe ? Quand j’utilise la propriété value sur cette liste, access plante.
Merci
Lorsqu’il y a un choix multiple, le résultat d’une sélection peut représenter plusieurs éléments. D’où le fait que Value (une valeur unique) n’a plus de sens. C’est pour cela qu’on remplace Value par ItemsSelected.
Stephane Brille > Une réponse un peu tardive, le temps de préparer une réponse qui se tienne : il y aura un article sur le sujet mardi prochain sur le blog. Stay tuned!
excusez-moi pour l’imprécision de mon message précédent, la limitation est bien sur de 255 caractères… La fonction Len compte mieux que moi 🙂
Bonjour,
Merci pour ces bons conseils. Un petit souci me gache un peu la vie en ce moment. Ma liste déroulante TexteChoix basée sur une requete SQL fonctionne parfaitement, mais la sélection de texte possible ne dépasse pas 240 caractéres. Or il s’agit d’afficher et de sélectionner dans la liste des morceaux de courriers « préfabriqués » qui sont parfois plus long…
Ma requete affiche la table correctement avec le champ complet. la selection tronque à 240 par exemple dans ce message
msgbox Me.textechoix.Itemdata(me.textechoix.listindex)
Si vous pouviez me mettre sur une piste ? je n’ai pas trouvé de renseignement concernant une éventuelle limitation. Merci d’avance
Merci, c’était vraiment clair, c’est agréable!
3ug3n > Je reprends le résumé, pour la mise en place des tables :
– UN projet-remède peut prendre en charge entre 0 et n problèmes
– UN projet-remède ne sert qu’une seule fois, même s’il est inefficace.
Et inversement, est-ce qu’un problème peut être liée à plusieurs remèdes ?
Bonjour Hervé!
Effectivement, ma présentation était un peu lapidaire ^^
Voilà, mettons que j’aie 5 problèmes (1,2,…5) – rien que sur Access, c’est complètement faux, mais ce n’est qu’un exemple 🙂
Je souhaite lancer un projet-remède « P-R I », pour traiter les problèmes #1 et #3: grâce à mon formulaire comportant la fameuse liste à choix multiple, je souhaite voir l’ensemble des problèmes à traiter, et cocher les #1 et #3 (donc les associer avec ce projet, en garder la mémoire)
Je souhaite ensuite lancer un projet-remède « P-R II », pour le pb #5 : comme je pars du principe que les #1 et #3 ont été résolus en « P-R I », je souhaite que ma liste à choix multiple ne me propose plus que les #2, #4, et #5.
Etc.
En résumé, pour répondre à vos questions: UN projet-remède :
– peut prendre en charge entre 0 et n problèmes (si il ne traite aucun problème, il est préventif, sinon il est curatif ; je n’ai (donc?) pas de relation entre mes 2 tables (sous AC2007))
– ne sert qu’une seule fois, même s’il est inefficace.
Est-ce que ces éléments vous permettent d’affiner votre diagnostic ?
Par avance merci !
3ug3n > Merci pour le retour 🙂
Avant de pouvoir répondre à la question, il me faut plus d’infos sur la modélisation : est-qu’un projet-remède est générique ou pas ?
En d’autres termes, est-ce qu’il peut servir plusieurs fois, s’appliquer à plusieurs problèmes ? Ou au contraire, est-ce qu’une fois appliqué à un problème, il ne peut plus servir ?
Bonjour !
Tout d’abord un grand bravo pour ce site qui est une véritable mine d’or!
Voilà, je ne sais pas si je poste dans le bon fil,mais bon, voilà mon souci :
J’ai :
– une table comportant des problèmes à traiter
– une table comportant des projets pour y remédier
– un formulaire « projets », avec une liste à sélection multiple où apparaissent les fameux problèmes. Ok.
>>> je souhaiterais que :
– mes problèmes cochés soient associés à un projet-remède (apparaissant donc dans le formulaire correspondant)
– ces problèmes cochés n’apparaissent plus dans la liste du formulaire du projet suivant (ils sont censés avoir été traités…)
L’idée de la liste est-elle pertinente dans ce cas ?
Si oui, comment faire? Si non,comment faire? ^^
Merci d’avance !
Sue > L’exemple donné en bas d’article s’applique à l’ouverture de formulaires. Pour ouvrir un état, il faut transformer l’instruction
DoCmd.OpenForm
(qui ouvre un formulaire) enDoCmd.OpenReport
(qui ouvre un état). Et adapter bien sûr le nom de l’état à ta base de données.Bonjour, est-ce que je peux me servire de cet exemple pour ouvrir un État ? Si oui, quelles modifications dois-je apporter car ça ne semble pas fonctionner et je n’y connais pas grand chose en VBA. Merci
Gef > Je ne connais pas ta base, mais je ne suis pas sûr que ce soit une bonne idée de stocker plusieurs valeurs dans un seul champ. Tu perds de l’info en faisant ça. Si tu peux préciser…
Bonjour merci pour cette aide
javoue je bugg pas mal sur les zones de liste multiples,
jaimerai que les elements choisis senregistrent dans un champ de ma base de donnee ( javoue je comprends pas pourquoi je narrive pas a enregistrer cela)
merci davance
sam > Si tu récupères ces enregistrements, tu en fais quoi ? Notamment, où est stocké ensuite le résultat, la sélection ?
Merci pour votre réponse
En fait je cherche à récuperer pour chaque enregistrement au niveau d’un formulaire les données selectionnées dans une liste à choix multiple et appartenant à un autre formulaire
Sam
Sam > Avant de répondre plus en détail, est-ce que le fait de transférer les données dans une autre table est une bonne idée ? Ça va créer des doublons, ce qui est souvent mauvais en base de données (sauf cas particulier bien sûr). Est-ce qu’il n’y aurait pas moyen de penser « relations » que « copie » dans ton projet ? Autrement dit : qu’est-ce que tu veux faire exactement ? 😉
Bonjour.
Comment faire pour récupérer les données d’une zone de liste à choix multiple d’une table1 pour remplir une autre table2.
Merci pour votre aide
Sam
steeve > Une requête ne peut pas utiliser de variable directement. Tu veux faire quoi de cette requête, exactement ?
Bonjour
merci pour ce tuto,
mais je n’arrive pas a l’appliquer à l’ouverture d’une requete qui utiliserai la variable strFiltre comme critère de la requete, si tu as une suggestion ele est la bienvenue, merci 🙂