Mais enfin Marc-L, je ne suis pas un expert en info.Citation:
encore un ignorant tout puissant derrière l'anonymat de son clavier ! -
Bon point grave pour le pouce à mon égard, sans rancune de ma part.
Mais j'aimerai bien solutionner mon pb.
Version imprimable
Mais enfin Marc-L, je ne suis pas un expert en info.Citation:
encore un ignorant tout puissant derrière l'anonymat de son clavier ! -
Bon point grave pour le pouce à mon égard, sans rancune de ma part.
Mais j'aimerai bien solutionner mon pb.
Mais t'en as aucun ‼
Sans réponse à la question évidente, difficile de t'aider !
Encore une fois, vu l'évènement Worksheet_Activate c'est impossible s'il s'agit bien de la liste que tu veux vider.
Si c'est la valeur alors change sa propriété Value …
Salut.
@esse2016,
Et si tu nous disais ce que tu souhaites réaliser, la finalité de ta demande? Peut-être pourrions-nous t'aiguiller mieux.
Parce que 22 messages,l'agressivité inutile qui monte et les pleurnicheries pour les -1, ça commence à faire beaucoup pour ce qui est annoncé comme étant un problème de remplissage de combobox ;)
L'alimentation de la liste déroulante demande deux lignes de code et pas plus lors de l'ouverture du classeur
comme cela fonctionne de mon côté depuis la sortie de la version 2003, un bail !
Pour peu d'être enfin sûr du besoin réel exprimé sans ambiguïté, clairement et exhaustivement …
Je suis bien d'accord. Mais comme on tourne autour du problème depuis pas mal de temps, j'imagine que le besoin initial, probablement mal "traduit" en code et donc mal exprimé, a besoin d'être exprimé en français, pour ne pas être brouillé par une esquisse de solution qui visiblement ne répond pas au problème...
Nous sommes donc dans l'attente de l'expression claire du besoin ... :whistle:
Bonjour Pierre,
D'accord avec tes propos.
J'essaye donc de reformuler:
je souhaite alimenter une combobox1 située dans une feuille excel ici la n°3.
L'alimentation est obtenue à partir de cellules d'une autre feuille ici la n°2
(exemple: mettre dans la combobox1 de la feuille3 que les villes commençant par la lettre "T" issues de la colonne "h" de la feuille2)
De plus, Je Souhaiterais qu'à chaque fois que je quitte excel en ayant sauvegardé, que ma combobox soit vide de façon qu'à la prochaine ouverture d'excel lorsque j'irai sur la feuille3 l' item de la combo choisit ne soit pas visible question "d'esthétisme". Ce passage est difficile à exprimer😓.
(Pour 2lignes de code hélas pour moi je n'ai pas le niveau...)
Merci pour les interventions de chacun.
Ok.
Le "gros" problème n'est donc pas, en tant que tel, le remplissage de la combobox.
Sur base d'une table de données appelée t_Villes illustrée ci-desous...
Pièce jointe 315023
Basiquement, une combobox se remplit en une ligne, si la plage qui sert le combobox existe telle qu'elle, comme le soulignait Marc...
Code:feuil3.cboCities.List = range("t_villes").value
De même, une combobox se vide en une ligne
il "suffit" donc d'appeler ces lignes de code au bon moment, c'est-à-dire lors du bon évènement.Code:feuil3.cboCities.Clear
En soi, ton problème initial est résolu... Sauf que d'après ton dernier message, tu ne veux prendre que certaines lignes de la table. Comme la plage n'existe pas en tant que telle, tu as deux solutions:
- préparer une plage qui correspond à ce que tu souhaites;
- charger ton combobox en bouclant sur les cellules pour tester si elles doivent être prises en compte ou pas.
En choisissant la première technique, le problème est donc de définir la plage qui pourra être passée à la propriété LIST de ton combo. Là aussi, tu as plusieurs moyens, selon les conditions à remplir. Dans ton cas, on pourrait trier la table puis définir la sous-plage qui commence par une lettre. Cela revient à écrire une fonction qui va renvoyer la plage correspondante (à mettre dans un module standard). Je propose une technique parmi d'autres:
Tu peux alors utiliser cette fonction au sein d'une procédure qui va charger ta combo (toujours dans un module standard)Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 Function getCities(FirstLetter As String) As Range Dim rng As Range Dim FirstRow Dim RowsCount As Long With Feuil2.Range("t_Villes").ListObject.Sort .SortFields.Clear .SortFields.Add Key:=Range("t_Villes"), Order:=xlAscending .Apply End With FirstRow = Application.Match(FirstLetter & "*", Range("t_Villes"), 0) If Not IsError(FirstRow) Then RowsCount = Application.CountIfs(Range("t_Villes"), FirstLetter & "*") Set getCities = Range("t_Villes")(FirstRow).Resize(RowsCount) End If End Function
Si tu dois charger ta combo à l'ouverture de ton classeur, tu auras alors une ligne à placer dans le code évèmentiel de l'ouverture du classeur (module ThisWorkBook si pas renommé)Code:
1
2
3
4
5
6
7
8 Sub FillCboCities() Dim rng As Range Set rng = getCities("T") If Not rng Is Nothing Then Feuil3.cboCities.List = rng.Value End If End Sub
Perso, j'aime bien mettre le code de vidange du combo dans une procédure, même pour une ligne, dans un module standardCode:
1
2
3 Private Sub Workbook_Open() FillCboCities End Sub
il te suffit d'appeler cette ligne lors de la fermeture du classeur (module ThisWorkBook)Code:
1
2
3 Sub ClearCboCities() Feuil3.cboCities.Clear End Sub
Code:
1
2
3 Private Sub Workbook_BeforeClose(Cancel As Boolean) ClearCboCities End Sub
On peut ne pas découper de cette manière, mais on écrit alors un code spaghetti à rallonges et dans deux mois, on ne s'y retrouve plus. En plus, on ne sait alors pas tester les portions de code isolément du reste. Puisque tu débutes en VBA, prends de suite les bonnes habitudes pour scinder ton code en fonctions/procédures qui font une partie de ton code bien définie. Ainsi, tu peux les tester séparément et les faire évoluer beaucoup plus facilement. Ce n'est pas plus compliqué à mettre en place, mais c'est 1000 fois plus simple pour la suite de ton travail!
Une autre technique pourrait consister à préparer la plage qui sert le combobox grâce à un filtre avancé. Cela te permettra une grande souplesse dans le choix des données à afficher dans la combo. Ce sera pour mon post suivant. Tu verras qu'il suffira de modifier la fonction getCities... Et tu auras un bonus gratuit... ;)
Avec un filtre avancé, tu vas gagner en souplesse, surtout si tu utilises un filtre formulé, comme illustré ici. Il suffit de rédiger une formule booléenne dans la zone de critère en prenant comme référence de cellule la première ligne de la table de données (ici, j'ai choisi d'extraire les villes dont la deuxième lettre est "a").
Pièce jointe 315038
Il te suffit alors d'une fonction qui applique le filtre avancé. Dans la construction de la feuille, il faut définir les plages qui serviront aux critères et à la récupération des données filtrées (dans mon code, cboFilter pour J1:J2 et cboList pour L1:L2).
Il faut évidemment modifier la ligne de FillCboCitiesCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 Function getCitiesByAdvancedFilter() As Range On Error Resume Next With Range("t_Villes").ListObject.Sort .SortFields.Clear .SortFields.Add Key:=Range("t_Villes"), Order:=xlAscending .Apply End With Application.DisplayAlerts = False Range("cbolist").EntireColumn.ClearContents Range("t_Villes[#All]").AdvancedFilter xlFilterCopy, Range("cboFilter"), Range("cbolist") Application.DisplayAlerts = True Set getCitiesByAdvancedFilter = Range("cbolist")(2).Resize(Application.CountA(Range("cbolist").EntireColumn) - 1) End Function
Voici le résultat avec les villes ayant a en deuxième lettre.Code:Set rng = getCitiesByAdvancedFilter
Pièce jointe 315039
Tu veux une liste des villes dont le nom contient moins de sept lettres? Tu n'as rien à modifier dans le code. Tu modifies simplement ton critère en J2 et tu relances FillCboCities... ;) Tu sors ainsi complètement le critère de choix des villes de ton code en permettant de décrire ce critère dans Excel. 100% de souplesse dans l'expression du critère.
Pièce jointe 315042
Pièce jointe 315044
Perso, j'aime moins la solution de boucler sur les lignes de la liste des villes, car il est plus malaisé de sortir l'expression du critère du code, ce qui amène à devoir modifier le code lorsque la règle de gestion est modifiée. Quand je peux éviter, j'évite...
En bonus, le fichier...
Monsieur Pierre, une petite parenthèse, juste me dire mon filtre ci-desous est ok ou pas
(Sans parler du combobox1.additem)
TbG est un tableau définit par dim TbG as long
C'est peut-être cela que Marc-L essayait de m'ouvrir les yeux. Car TbG à l'allure d'un range...
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 With Sheets(2) If Not WorksheetFunction.CountIf(.Range("B9", .Range("L" & Rows.Count).End(xlUp)), "T") = 0 Then TbG = .Range("B9", .Range("L" & Rows.Count).End(xlUp)) For Ligne = 1 To UBound(TbG, 1) 'On boucle sur TbG image de la sélection de B9 à Range....End(xlUp) If TbG(Ligne, 7) = "T" Then 'cas du nom commençant par la lettre T Worksheets(3).ComboBox1.AddItem TbG(Ligne, 11) & "_" & TbG(Ligne, 1) 'remplir la combobox End If Next Ligne End If End With End Sub
Non.
Si tu boucles sur tes lignes, tu ne dois pas passer par un tableau, tu dois simplement passer la valeur de la cellule, éventuellement recomposée avec le tiret et une concaténation, lors du AddItem (qui ajoute un item dans la première colonne du combo).
De plus, on ne définit pas un tableau avec dim tbg as long. Là, tu définis une variable de type long, pas du tout un tableau, dont tu n'as a priori pas besoin.
Inspire-toi du code suivant, toujours sur base de ma table t_Villes
Code:
1
2
3
4
5
6
7
8 Sub FillCboCitiesWithLoop() Dim c As Range Feuil3.cboCities.Clear For Each c In Range("t_Villes") If c.Value Like "T*" Then Feuil3.cboCities.AddItem c.Value Next End Sub
…soir,
+2 :plusser: Pierre pour les explications et méthodes ;)
Et je t'ai pourtant déjà donné plusieurs fois la solution !
Une troisième voie sans boucle via le moteur de formule de calculs en deux lignes de code,
la base - la formule - étant accessible à tout débutant pour peu de savoir lire …
Et si tu la donnais, ta technique? Parce que répéter 10 fois qu'il suffit d'une formule accessible à tout débutant mais ne pas donner la solution, ça ne fait pas avancer le schmilblick, à mon avis :roll:Citation:
Envoyé par Marc-L;9648810[...
Sauf à ne pas comprendre de quoi tu parles, ce qsui est toujours possible, il me semble que j'ai donné une solution avec le moteur de formules, qui utilisait MATCH et COUNTIFS... Mais je suis preneur d'une formule générique si tu en as une ;)
J'attends déjà le retour du demandeur afin de savoir où il en est …
Une fois que de son côté c'est d'équerre, je lui ferais revisiter avec plaisir les bases d'Excel
- Penser Excel avant VBA ! - en le guidant par étape d'Excel vers le VBA,
une bien meilleure méthode d'apprentissage que de livrer du tout cuit qu'il ne pourrait comprendre !
Enseigner la pêche au lieu de fournir du poisson … (Confucius)
Voie déjà présente dans plusieurs discussions de ce forum, une ligne de code pour alimenter la liste déroulante
(deux ou plus pour une meilleure lisibilité pour un débutant).
Une autre ligne de code pour l'évènement d'ouverture du classeur.
Bonjour,
Le plus "simple" n'est-il pas d'utiliser la fonction Filter?
https://msdn.microsoft.com/fr-fr/lib...(v=vs.90).aspx
Il suffit de :
- déterminer la plage de cellules à filtrer,
- transposer cette plage (avec Application.Transpose),
- de filtrer cette plage (avec Filter(TbValues, Filtre))
- de placer cette liste filtrée dans la List de la ComboBox
Ce qui peut, effectivement, être fait en une seule ligne de code.
exemple: mettre dans la combobox1 de la feuille3 que les villes commençant par la lettre "T" issues de la colonne "h" de la feuille2
Dans le module de code de la feuille Feuil3 :
Qui plus est, ce code est relativement rapide. Si 25 000 communes, il s'exécute en 0,10 seconde...Code:
1
2
3
4
5
6
7
8
9 Option Explicit Private Sub Worksheet_Activate() ComboBox1.List = Filter(Application.Transpose(Sheets("Feuil2").Range("H1:H" & Sheets("Feuil2").Range("H" & Rows.Count).End(xlUp).Row).Value), "T") End Sub Private Sub Worksheet_Deactivate() ComboBox1.Clear End Sub
Pour le côté "esthétique", ajouter dans le module de code ThisWorkbook :
Code:
1
2
3
4
5
6
7
8
9 Option Explicit Private Sub Workbook_BeforeClose(Cancel As Boolean) Sheets("Feuil3").ComboBox1.Clear End Sub Private Sub Workbook_Open() Sheets("Feuil2").Activate End Sub
Salut Franck,
Ton code reprend ce qui commence par T parce que tu supposes que seule la première lettre est en majuscule, car sauf erreur de ma part, Filter extrait tout ce qui contient la valeur de l'argument MATCH (ici, en l'occurrence "T").
Je ne suis pas convaincu que cette technique offre la souplesse des filtres avancés :?
Pierre,
Exact.
J'ai supposé les villes saisies comme suit : Lille, Lens, Marseille, etc...
En Belgique, nous avons des villes qui foutent la panade, mais je suis sûr qu'il y en a en France... Villers Le Temple (B), Marsac sur Tarn (F), par exemple... :mouarf:
Salut Franck !
J'utilise effectivement Filter pour séparer le Grain de l'Ivraie mais après la formule de concaténation …
Salut,
Vous m'avez donc perdu...
Marc, si tu utilises une formule (de concaténation ou autre), tu utilises donc une seconde colonne?
De plus, je ne vois pas avec quoi concatener pour l'obtention d'un résultat avec Filter...