UserForm et listes déroulantes liées entre elles
Bonjour à tous et toutes et je vous souhaite mes meilleurs vœux pour cette année 2025,
Voici ma problématique, j'ai crée une base pour répertorier dans trois feuilles différentes, Particuliers, Professionnels et Fournisseurs.
J'ai ensuite crée pour la première feuille un formulaire UserForm avec les informations nécessaires.
Je me retrouve cependant bloquée sur une option que j'aimerai réussir à mettre en place, c'est à dire que quand je tape le code postal sur CodePostalBox ça me mette les villes en lien dans la ComboBox d'à coté VILLEComboBox.
Sur la feuille Villes_Pays, on retrouve un tableau avec le nom des communes, les codes postaux et une liste de codes postaux sans doublons, ni vides.
Je joins fichier et code.
J'ai dejà réussi à faire ça sans VBA, mais là je bloque pour le mettre dans l'UserForm, j'avais testé un bout de code avec autofilter, mais je n'ai pas réussi à le mettre en place.
Je suis débutante, et je vous remercie d'avance de votre aide.
À très vite,
Jennyx
Private Sub AnnulerFicheParticulierButton_Click()
' Remise à zéro les box de la UserForm
PrénomBox.Text = ""
NomBox.Text = ""
AdresseBox.Text = ""
CodePostalBox.Text = ""
VILLEComboBox.Text = ""
PaysBox.Text = ""
TélPersoBox.Text = ""
EmailPersoBox.Text = ""
EntrepriseBox.Text = ""
StatutBox.Text = ""
TélProBox.Text = ""
EmailProBox.Text = ""
' Cacher la UserForm
NouveauParticulierUF.Hide
' Positionner le focus sur PrénomBox
PrénomBox.SetFocus
' Message de validation finale
MsgBox "La fiche a bien été annulée !"
End Sub
Private Sub EnregistrerFicheParticulierButton_Click()
' Vérification si tous les champs sont remplis
If PrénomBox.Text = "" Or _
NomBox.Text = "" Or _
AdresseBox.Text = "" Or _
CodePostalBox.Text = "" Or _
VILLEComboBox.Text = "" Or _
PaysBox.Text = "" Or _
TélPersoBox.Text = "" Or _
EmailPersoBox.Text = "" Or _
EntrepriseBox.Text = "" Or _
StatutBox.Text = "" Or _
TélProBox.Text = "" Or _
EmailProBox.Text = "" Then
' Afficher un message d'erreur
MsgBox "Veuillez remplir tous les champs avant d'enregistrer.", vbCritical
Else
' Mettre à jour le compteur
Cells(1, 1).Value = Cells(1, 1).Value + 1
' Récupérer la valeur du compteur
Dim compteur As Integer
compteur = Cells(1, 1).Value
' Formater l'ID
Dim id As String
id = "IDPa" & Format(compteur, "000")
' Recherche de la première ligne vide
l = 5
While Not IsEmpty(Cells(l, 5))
l = l + 1
Wend
' Saisir les informations Particulier
Cells(l, 3) = Date ' Ajout de la date d'entrée dans la première colonne
Cells(l, 4) = PrénomBox.Text
Cells(l, 5) = NomBox.Text
Cells(l, 6) = AdresseBox.Text
Cells(l, 7) = CodePostalBox.Text
Cells(l, 8) = VILLEComboBox.Text
Cells(l, 9) = PaysBox.Text
Cells(l, 10) = TélPersoBox.Text
Cells(l, 11) = EmailPersoBox.Text
Cells(l, 12) = EntrepriseBox.Text
Cells(l, 13) = StatutBox.Text
Cells(l, 14) = TélProBox.Text
Cells(l, 15) = EmailProBox.Text
Cells(l, 2) = id ' Ajouter l'ID dans la première colonne
' Remise à zéro les box de la UserForm
PrénomBox.Text = ""
NomBox.Text = ""
AdresseBox.Text = ""
CodePostalBox.Text = ""
VILLEComboBox.Text = ""
PaysBox.Text = ""
TélPersoBox.Text = ""
EmailPersoBox.Text = ""
EntrepriseBox.Text = ""
StatutBox.Text = ""
TélProBox.Text = ""
EmailProBox.Text = ""
' Cacher la UserForm
NouveauParticulierUF.Hide
' Positionner le focus sur PrénomBox
PrénomBox.SetFocus
' Message de validation finale
MsgBox "Fiche enregistrée avec succès !"
End If
End SubBonjour
Vous pouvez tester ce code
Private Sub CodePostalBox_Change()
Dim TS As ListObject
Dim c As Range
Dim lig As Long
Dim prem As String
If encours = True Then Exit Sub
VILLEComboBox.Clear
If Len(CodePostalBox) >= 4 Then 'verifier nombre de caractere dans textbox
Set TS = Range("TAB_VillesEtCp").ListObject
With TS
Set c = .ListColumns(2).DataBodyRange.Find(CodePostalBox.Value, LookIn:=xlValues, lookat:=xlWhole)
If Not c Is Nothing Then
prem = c.Address
Do
lig = c.Row - .HeaderRowRange.Row
VILLEComboBox.AddItem .DataBodyRange(lig, 1).Value
Set c = .ListColumns(2).DataBodyRange.FindNext(c)
Loop While Not c Is Nothing And c.Address <> prem
End If
End With
End If
End SubNB :
- attention à votre instruction HIDE qui revient à masquer l'usf à l'arrière plan.Si vous ne l'utilisez pas mettez plutôt UNLOAD ME pour décharger l'usf
- Les autres macros pourraient être revue dans votre cas. A voir si intérêt que je jette un oeil
- A voir aussi si cela n'aurait pas été plus utile de n'avoir qu'une seule feuille en ajoutant une colonne pour les termes "Particulier", "Professionnel", ....
- une seul usf serait plus pratique si vous ajoutez une combox de choix entre particulier, prof ou fournisseur. A voir l'impact au niveau de textbox nécessaire dans chaque cas
Si ok et terminé pensez à cloturer le fil
Crdlt
Merci beaucoup Dan pour votre réponse très rapide et qui marche parfaitement
Pour votre NB :
attention à votre instruction HIDE qui revient à masquer l'usf à l'arrière plan.Si vous ne l'utilisez pas mettez plutôt UNLOAD ME pour décharger l'usf
J'ai suivi un tuto sur YT donc j'ai fais à la lettre ce qui était montré. Je n'avais pas forcément besoin de ce bouton annuler la fiche en fait, mais quand j'ai essayé de l'adapter à mon système ça ne marchait pas. Bref si je comprend bien HIDE ne ferme pas complètement la fenêtre de formulaire de saisie, en le laissant en arrière-plan ? Et si je le remplace par UNLOAD ME ça sera le cas?
A voir aussi si cela n'aurait pas été plus utile de n'avoir qu'une seule feuille en ajoutant une colonne pour les termes "Particulier", "Professionnel", ....
En fait je vais rajouter des feuilles par la suite liées pour créer automatiquement des devis, factures, calcul de prix de revient, donc à la limite oui je peux réunir au moins les Particuliers et les Professionnels. Les fournisseurs ça sera plus pour une liaison avec les prix de revient.
Mais c'était plus simple de premier abord pour moi d'avoir 3 feuilles avec 3 codes couleurs différents et 3 UserForm.
Je suis peut-être dans le faux en me disant que ça serait plus simple de cette façon
Bref si je comprend bien HIDE ne ferme pas complètement la fenêtre de formulaire de saisie, en le laissant en arrière-plan ? Et si je le remplace par UNLOAD ME ça sera le cas?
Exactement vous avez compris.
Pour ma part, le HIDE se justifie si par exemple :
- vous voulez aller contrôler sur votre feuille ce qui est envoyé depuis l'USF puis continuer à entrer des données via l'USF. Cela va éviter de relancer des codes d'ouverture d'une USF (vous n'en avez pas dans votre cas mais cela peut arriver)
- vous avez plusieurs USF et que vous passez d'une à l'autre. exemple : vous avez une USF recherche que vous appelez depuis une USF principale et en fonction du résultat de la recherche vous rapatriez des données dans l'usf principale.
En fait je vais rajouter des feuilles par la suite liées pour créer automatiquement des devis, factures, calcul de prix de revient, donc à la limite oui je peux réunir au moins les Particuliers et les Professionnels. Les fournisseurs ça sera plus pour une liaison avec les prix de revient.
Ok. A voir en évolution de votre fichier
Mais c'était plus simple de premier abord pour moi d'avoir 3 feuilles avec 3 codes couleurs différents et 3 UserForm.
cela peut toujours évoluer par après bien que c'est toujours mieux d'y penser au départ
Quelques changements à faire :
1. Le code Private Sub EnregistrerFicheParticulierButton_Click() peut être modifié comme suit :
Private Sub EnregistrerFicheParticulierButton_Click()
Dim TS As ListObject
Set TS = Range("TAB_Particuliers").ListObject
' Vérification si tous les champs sont remplis
If PrénomBox.Text = "" Or _
NomBox.Text = "" Or _
AdresseBox.Text = "" Or _
CodePostalBox.Text = "" Or _
VILLEComboBox.Text = "" Or _
PaysBox.Text = "" Or _
TélPersoBox.Text = "" Or _
EmailPersoBox.Text = "" Or _
EntrepriseBox.Text = "" Or _
StatutBox.Text = "" Or _
TélProBox.Text = "" Or _
EmailProBox.Text = "" Then
' Afficher un message d'erreur
MsgBox "Veuillez remplir tous les champs avant d'enregistrer.", vbCritical
Exit Sub
End If
' Récupérer la valeur du compteur
Dim compteur As Integer
compteur = Range("TAB_Particuliers").ListObject.ListRows.Count + 1
' Formater l'ID
Dim id As String
id = "IDPa" & Format(compteur, "000")
Dim lig As Integer
'Saisir les informations Particulier
With TS
If .ListRows.Count = 0 Then
.ListRows.Add: lig = 1
Else: .ListRows.Add: lig = .ListRows.Count 'insérer à la dernière ligne
End If
With .DataBodyRange
.Item(lig, 1) = id ' Ajouter l'ID dans la première colonne
.Item(lig, 2) = Date ' Ajout de la date d'entrée dans la première colonne
.Item(lig, 3) = PrénomBox.Text
.Item(lig, 4) = NomBox.Text
.Item(lig, 5) = AdresseBox.Text
.Item(lig, 6) = CodePostalBox.Text
.Item(lig, 7) = VILLEComboBox.Text
.Item(lig, 8) = PaysBox.Text
.Item(lig, 9) = TélPersoBox.Text
.Item(lig, 10) = EmailPersoBox.Text
.Item(lig, 11) = EntrepriseBox.Text
.Item(lig, 12) = StatutBox.Text
.Item(lig, 13) = TélProBox.Text
.Item(lig, 14) = EmailProBox.Text
End With
End With
MsgBox "Fiche enregistrée avec succès !", "Enregistrement"
Call Efface
End sub2. Ajouter ce code pour effacer les données une fois l'enregistrement effectué
Sub Efface()
Dim c As Control
encours = True
For Each c In Me.Controls
Select Case TypeName(c)
Case "TextBox"
c.Value = vbnullstring
Case "ComboBox"
c.Value = vbnullstring
c.ListIndex = -1
End Select
Next c
encours = False
End Sub3. Modifications à apporter (important !)
- dans l'USF, en première ligne (donc juste avant le code Private Sub AnnulerFicheParticulierButton_Click(), ajoutez ceci
Dim encours As Boolean- dans le code que je vous ai donné avant, ajoutez cette ligne juste en dessous de la ligne Dim Prem as string
If encours = True Then Exit SubRem : J'ai rajouté cette "ligne IF encours......" dans le code de mon post précédent
NB : le numéro de compteur mentionné en A1 ne sert plus. Vous pouvez l'effacer
Crdlt
Merci beaucoup Dan pour toutes ces explications et ces nouveaux codes, je vais tâcher de les mettre en application, mais avant je vais réfléchir à ce que vous m'avez dis concernant le fait de mieux réfléchir à la finalité de mon projet. Encore un grand merci pour votre aide et en attendant je met le problème résolu.
Belle journée à vous.