Capter la valeur d'une list box pour trouver le nom d'un onglet
Bonjour à tous,
Je suis débutant sur VBA et je cherche désespérément une solution à mon problème... J'ai parcouru différents forums mais je n'ai pas réussi à trouver une solution qui me convienne.
Je me tourne donc vers vous en espérant que vous pourrez m'aider
Mon problème est très simple : J'ai 10 fichiers dans lesquels 12 onglets sont intégrés. Ces 12 onglets font référence au 12 mois d'une année.
Ex: mon workbooks("TEST1") contient worksheets("Janvier 2018"), la deuxième worksheets("Février 2018") et ainsi de suite jusqu'à Décembre 2018.
Les noms des onglets de mes 10 workbooks sont strictement identiques.
Ma macro effectue des copier/coller et des calculs pour rapatrier les données des 10 workbooks du mois en cours dans un autre classeur qui consolide les données des 10 fichiers. La macro fonctionne très bien, aucun problème de ce côté là.
Cependant, je n'ai pas trouvé un moyen de demander à la macro d'aller chercher les données dans l'onglet du mois en cours.
Ex: nous sommes en septembre 2018, j'ouvre mes 10 workbooks et je renomme l'onglet "Septembre 2018" en "MOIS". La macro recherche donc dans les 10 workbooks l'onglet "MOIS" et copie/colle les données :
Workbooks("REPORTmacro.xlsm").Worksheets("BUDGET").Range("B52").Value
_=Workbooks("TEST1.xlsx").Worksheets("MOIS").Range("C10").Value
Workbooks("REPORTmacro.xlsm").Worksheets("BUDGET").Range("B53").Value
_=Workbooks("TEST2.xlsx").Worksheets("MOIS").Range("C10").Value
J'aimerais donc avoir une listbox (via userform?) qui invite l'utilisateur à sélectionner le mois en cours et ainsi remplacer dans mon code le "MOIS" par la valeur sélectionnée dans la list box.
EX: l'utilisateur saisit via la listbox "Septembre 2018", alors le code de la macro s'adapte comme suit :
Workbooks("REPORTmacro.xlsm").Worksheets("BUDGET").Range("B52").Value
_=Workbooks("TEST1.xlsx").Worksheets("Septembre 2018").Range("C10").Value
Workbooks("REPORTmacro.xlsm").Worksheets("BUDGET").Range("B53").Value
_=Workbooks("TEST2.xlsx").Worksheets("Septembre 2018").Range("C10").Value
En bref, cela m'éviterait d'ouvrir chaque mois les 10 classeurs et de renommer l'onglet du mois en cours par "MOIS".
Je vous remercie par avance pour vos conseils et vous souhaite une très bonne journée
Romain
Bonjour,
Ton système me paraît bien compliqué...
Tu mets en place ton Userform, et tu définis une fonction de ce type :
Function MoisEnCours()
Dim mois$
With UserForm1
.Show
mois = .listBox1.Value
End With
Unload UserForm1
MoisEnCours = mois
End FunctionDans ta proécédure de consolidation, tu l'appelles pour recueillir le mois dans une variable String (mois par exemple !)
mois = MoisEnCours()Et dans ton code : ...Worksheets(mois)...
NB- Dans le code de ton Userform, tu ne décharges pas ce dernier, tu le masques. C'est la fonction qui le déchargera après récupération de la valeur de la ListBox.
Cordialement.
Bonjour MFerrand,
Merci pour ta réponse rapide
Merci pour ces conseils, c'est exactement ce que je souhaitais, tu viens de me faire économiser 10 minutes de mon temps chaque mois
Je passe le sujet en résolu
Bien cordialement
Bonsoir à tous,
Je ré-ouvre le sujet car je pense que je dois mal m'y prendre
J'ai bien créé le userform, et dans le userform, en cliquant sur le bouton "OK", j'ai rentré le code suivant :
Sub CommandButton1_Click()
Dim mois$
With UserForm4
mois = .ListBox1.Value
End With
Unload UserForm4
MoisEnCours = mois
End SubEn cliquant sur "OK" le code est donc censé charger la valeur choisie. J'ai mis en PJ la screenshot de mon userform.
Dans mon code de consolidation, voici le code que j'ai mis au début:
Private Sub Macro_Reporting()
Dim mois As String
mois = CommandButton1_Click()et dans mon code, j'appelle la feuille :
Workbooks("FIESSO.xlsx").Worksheets(mois).Range("C10").ValueJe charge mon formulaire dans une procédure Sub juste avant avec le code suivant :
Sub Run_the_Macro()
Load UserForm4
UserForm4.ShowEt cette même procédure call Private Sub Macro_Reporting()
Quand je lance la macro, une erreur de compilation s'affiche et indique "Sub ou Function non définie". En PJ le screenshot du débogage
Savez-vous ce que j'ai loupé ?
Merci par avance pour aide précieuse
Je ne vois pas de fonction... Relis mon post et tiens-toi à ce que j'ai défini pour avoir un dispositif qui fonctionne.
J'ai bien rentré la function dans mon code de consolidation mais lorsque le userform s'affiche et que je clique sur "OK" rien ne se passe...
Voci le début de mon code dans lequel j'appelle ma function :
Sub Run_the_Macro()
Dim debut As Date, temps As Date, Fin As Date
debut = Time
Call MoisEnCours
UserForm4.Hide
DoEvents
Application.Calculation = xlCalculationManualet j'ai repris le code de la function que j'ai placé dans le module 1 et non dans le userform
Function MoisEnCours()
Dim mois$
With UserForm4
.Show
mois = .ListBox1.Value
End With
Unload UserForm4
MoisEnCours = mois
End FunctionCe que je n'arrive pas à saisir c'est qu'il faut bien que je lui dise "si click sur OK, alors exécution de la function"
C'est cette ligne qui appellera la fonction :
mois = MoisEnCours()Et ton code Userform doit se limiter à :
Sub CommandButton1_Click()
Me.Hide
End SubCordialement.
Merci MFerrand
Mais ça ne fonctionne toujours pas... Je dois vraiment louper quelque chose
J'ai une sub principale qui appelle mes autres Sub :
Sub Launch_the_Macro()
Dim mois As String
mois = MoisEnCours()
DoEvents
Application.Calculation = xlCalculationManual
Load UserForm1 'message d'attente
UserForm1.Caption = "Please wait!"
UserForm1.Show False
UserForm1.Repaint
DoEvents
'Application.Cursor = xlWait
Application.ScreenUpdating = False l
Call Clearcells
Call OuvrirClasseurs
Call Macro_Reporting
Call FermerClasseursDans ma sub "Macro_Reporting" se trouve les feuilles auxquelles je dois faire référence.
Private Sub Macro_Reporting()
Dim mois As String
mois = UserForm4.ListBox1.Value
Workbooks("REPORTmacro.xlsm").Worksheets("BUDGETS").Range("B52").Value = Workbooks("FIESSO.xlsx").Worksheets(mois).Range("C10").ValueEt pourtant la macro débogue et souligne mois = UserForm4.ListBox1.Value dans ma Sub Macro_Reporting()....
Dans mon module j'ai bien inséré ta fonction :
Function MoisEnCours()
Dim mois$
With UserForm4
.Show
mois = UserForm4.ListBox1.Value
End With
Unload UserForm4
MoisEnCours = mois
End FunctionEssaie de comprendre :
ton Userform4 est dédié pour le renvoi de mois selon ta sélection,
la seule procédure qui doit l'appeler est la fonction !
la fonction étant en place de même que le Userform4, partout ailleurs, ayant besoin de définir le mois, tu le prélève dans une variable ainsi :
mois = MoisEnCours()et tu t'en sers.
Mais il y a toujours quelque chose que je ne comprends pas... J'ai l'impression que la valeur la liste box n'est pas chargée... voici en PJ le message d'erreur : la macro débogue et m'indique qu'elle ne trouve pas "mois"... Je ne comprends vraiment pas ce qui manque...
Je n'ai pas changé le code de ma sub principale :
Sub Launch_the_Macro()
Dim mois As String
mois = MoisEnCours()
DoEvents
Application.Calculation = xlCalculationManual
Load UserForm1 'message d'attente
UserForm1.Caption = "Please wait!"
UserForm1.Show False
UserForm1.Repaint
DoEvents
'Application.Cursor = xlWait
Application.ScreenUpdating = False l
Call Clearcells
Call OuvrirClasseurs
Call Macro_Reporting
Call FermerClasseursPeut-être dois-je activer le workbook? Workbooks("FIESSO.xlsx").activate? Le fichier est bien ouvert, la macro ouvre automatiquement les fichiers
Tu définis bien ta variable mois dans la proc. Launch_the_Macro avec : mois = MoisEnCours(), mais rien de tel dans ta proc. Macro_Reporting : tu utilises une variable mois sans l'avoir initialisée (dans ta dernière citation) et dans la citation précédente tu le faisais par : mois = UserForm4.ListBox1.Value.
Dans les deux cas la variable mois ne pourra contenir qu'un chaîne vide ! Soit la valeur ""
Peut-être dois-je activer le workbook?
JAMAIS ! N'ajoute pas des lignes de code inutiles à celles que tu as déjà !
Il convient dans l'immédiat de te rendre compte que initialisant une variable dans une procédure, elle l'est et est utilisable dans cette procédure, mais n'est pas définie dans les procédures que tu appelles à partir de cette dernière.
Il te faut donc soit l'initialiser à nouveau dans chacune des porcédures appelées où tu comptes l'utiliser, soit la passer en argument aux procédures appelées à partir de ta procédure appelante.
Mais son initialisation repose toujours sur la fonction définie à cet effet, uniquement.
Cordialement.
Merci MFerrand, tes explications sont très claires et en effet je comprends la logique
Cependant, je ne peux pas initialiser ma variable avec
mois = MoisEnCours()dans ma sub Macro_Reporting car, si j'ai bien compris, le userform s'ouvrirait de nouveau pour demander de sélectionner la même information qui a déjà été demandée par la sub principale Launch_the_Macro. De plus, j'ai trois autres sub qui font appel à "mois". Cela signifierait que le formulaire s’ouvrirait 4 fois au cours du déroulement de la macro pour demander exactement la même information... Et en effet, j'ai testé, cela fonctionne très bien, mais le formulaire s'ouvre 4 fois
La solution réside donc dans ce que tu appelle les arguments. Cependant, je n'ai aucune idée de ce que c'est
Quelque chose comme ceci? Placé dans ma sub principale :
Call Macro_Reporting & mois=UserForm4.ListBox1.ValueExemple :
Déclaration de procédure :
Sub Macro_Reporting(mois As String)Appel de la procédure :
Macro_Reporting moisNB- le nom de la variable et le nom de l'argument sont ici identiques, mais ils pourraient être différents, cela reviendrait au même.
NB2- Si tu utilises Call (c'est que tu aimes écrire plus que nécessaire !
Call Macro_Reporting(mois)Cordialement.
Merci beaucoup cela fonctionne parfaitement
J'aurais une tête dernière question, pour ma compréhension, concernant la fonction :
Function MoisEnCours()
Dim mois As String
With Pickuplist
.Show
mois = Pickuplist.ListBox1.Value
End With
Unload Pickuplist
MoisEnCours = mois
End FunctionA quoi sert la dernière ligne "MoisEnCours =mois"?
C'est la ligne-clé qui caractérise une fonction, celle qui renvoie le résultat : NomFonction = résultat, et qui fait que lorsque tu appelles une fonction pour recueillir un résultat, tu puisses effectivement l'obtenir.
Cordialement.
Merci beaucoup pour ton temps, tes conseils, tes explications et ta patience
Tout fonctionne très bien et le plus important : je comprends le cheminement
Je te souhaite une agréable soirée et sûrement à bientôt
Romain
Bonne continuation.