Microsoft 365 excel vba

PHV62

XLDnaute Junior
bonjour peut on utiliser un bouton dans un formulaire pour remplir les textbox de ce formulaire

je m explique dans le formulaire il y a 7 textbox je les remplis j appuie sur ajouter ca s ajoute dans la feuil1
avec le combobox je choisis ce nom que j ai remplie précédemment
tous les renseignement s affiche correctement a cote d un textbox il y a un bouton je voudrais que quand j appuie sur ce bouton il remplie les textbox qui correspondent a cette ligne
merci de votre aide
phv
 

Pièces jointes

  • Classeur1 test.xlsm
    24.3 KB · Affichages: 37

soan

XLDnaute Barbatruc
Inactif
Bonjour PHV62,

je ne joins pas de fichier, car il suffit d'ajouter une ligne de code dans la sub Job() :​

VB:
Private Sub Job(chn$, a As Byte, b As Byte)
  If chn = "" Then Exit Sub
  ComboBox1.AddItem chn: dv = dv + 1
  cel.Offset(, a) = chn: cel.Offset(dv) = chn: cel.Offset(dv, b) = cel
  If b = 2 Then cel.Offset(dv, 3) = TextBox2
End Sub

c'est la ligne juste avant le End Sub, qui commence par If b = 2

soan
 

PHV62

XLDnaute Junior
Bonjour PHV62,

je ne joins pas de fichier, car il suffit d'ajouter une ligne de code dans la sub Job() :​

VB:
Private Sub Job(chn$, a As Byte, b As Byte)
  If chn = "" Then Exit Sub
  ComboBox1.AddItem chn: dv = dv + 1
  cel.Offset(, a) = chn: cel.Offset(dv) = chn: cel.Offset(dv, b) = cel
  If b = 2 Then cel.Offset(dv, 3) = TextBox2
End Sub

c'est la ligne juste avant le End Sub, qui commence par If b = 2

soan
bonjour soan

j ai chercher j ai trouve l erreur dans ton fichier et également dans le mien
encore merci des renseignements

j ai encore des questions bien sur! quand je remplie les textbox comment peut on faire pour que si le nom du père , de la mère existe déjà dans la colonne A ils ne peuvent s'inscrire dans cette colonne car sinon j aurai des doublons
 

soan

XLDnaute Barbatruc
Inactif
Bonjour PHV62,

dans ton post #32, tu as écrit :
«
mais il y a une erreur
l'épouse a comme enfant son mari au lieu d'avoir les enfants
»


il n'y a pas d'erreur : comme dans la colonne B "épouse" tu n'as mis que des numéros, j'avais pensé que tu ne voulais pas l'ajouter dans la colonne A "Personne" ! donc je n'ai ajouté en A que les personnes de C à G, et pour ça, les résultats étaient ok ! mon code VBA n'était tout simplement pas prévu pour ta nouvelle info supplémentaire comme quoi il faut ajouter aussi l'épouse !

note bien que pour les 2 parents (père et mère), il suffit d'ajouter une seule personne en colonne E : enfant1 ; pour les 3 enfants (enfant1 ; enfant2 ; enfant3), il suffit d'ajouter une seule personne en colonne C : nom prénom ; mais si on ajoute l'épouse : a) c'est seulement si le couple n'a eu aucun enfant qu'on ajoute cette seule personne : le mari (pour cette raison, j'ai renommé la colonne B en « conjoint ») ; b) on ajoute en plus autant d'enfant que le couple en a eu ; même si tu as trouvé une solution pour ajouter correctement l'épouse, mon code VBA initial n'est pas du tout adapté pour cela ! aussi, je l'ai beaucoup modifié ! et même, j'ai fait plein d'modifs dans le UserForm et son code VBA !


fais d'abord les tests avec le nouveau fichier joint, y compris pour l'épouse ; et vérifie aussi qu'il te sera impossible d'ajouter une personne déjà existante ➯ tu n'auras plus de doublons ! :)

pour ouvrir "Formulaire", fais Ctrl e ou clique sur le bouton Formulaire ; tu peux en sortir aussitôt en appuyant sur la touche Échap (si tu es sur le 1er champ « nom prénom : » et si ce champ est vide) ; tu verras que j'ai ajouté un bouton effacer ; il ne supprime aucune donnée de la feuille de calcul, c'est juste pour effacer les champs du UserForm ; c'est très pratique après une recherche d'une personne, quand tu veux ajouter une nouvelle personne : tu effaces d'abord les champs, puis tu saisis les nouvelles valeurs.


dans le UserForm, j'ai changé tous les noms des contrôles :

* ComboBox1 est devenu cbx1 (c'est plus court)

* TextBox1 à TextBox7 sont devenus tbx0 à tbx6

* TextBox8 est devenu tbxDN (DN pour Date de Naissance)

IMPORTANT : si plus tard tu veux ajouter d'autres enfants, tu pourras le faire sans avoir besoin de renommer l'ancien TextBox8 ; et là, pour par exemple 5 enfants supplémentaires, tu peux ajouter 5 TextBox en les nommant tbx7 à tbx11 ; bien sûr, sur "Feuil1" tu devras aussi ajouter 5 colonnes supplémentaires avant la colonne H ; donc cette colonne "date naissance" passera en colonne M.​



dans le code VBA de UserForm1 :

j'ai changé presque tout ! ne cherche plus de sub Job() : y'en n'a plus ; j'ai déclaré au niveau global 3 constantes, et en cas d'ajout d'autre(s) enfant(s) tu n'auras que la 1ère constante NbEnf à changer ; j'ai mis beaucoup de commentaires dans le code VBA.


code VBA complet de UserForm1 (136 lignes) :​

VB:
Option Explicit 'pour la déclaration explicite des variables
'ce UserForm est appelé par la sub FORMULAIRE() (bouton "Formulaire")

Dim Ws As Worksheet 'variable pour un objet Worksheet, de niveau module,
'donc portée globale pour tous les Controls de ce UserForm

Const NbEnf As Byte = 3 'Nombre d'enfants maximum ; actuellement : 3 ;
'sera à ajuster si tu ajoutes d'autres colonnes pour plus d'enfants.

Const colDN As Byte = NbEnf + 5 'colonne de la Date de Naissance : 8 = H ;
'sera plus à droite si tu ajoutes d'autres colonnes pour plus d'enfants ;
'attention : tu ne devras PAS CHANGER 5 + NbEnf !

Const itbDE As Byte = NbEnf + 3 'index textbox dernier enfant ; ici : 6

Dim flag As Byte 'ATTENTION : NE PAS ENLEVER !!! (explications dans le code VBA)

Private Sub FillUF(lig&) 'sub appelée par cbx1_Change() et par GoParent()
  Dim i As Byte: Application.ScreenUpdating = 0: tbxDN = Ws.Cells(lig, colDN)
  For i = 0 To itbDE: Controls("tbx" & i) = Ws.Cells(lig, i + 1): Next i
End Sub

Private Sub cbx1_Change() 'liste déroulante
  'si flag = 1, sortir, car c'est un appel implicite depuis la sub cmdModif_Click()
  'MAIS AVANT de sortir, on met flag à 0, sans quoi choisir un nouvel item dans la
  'liste déroulante ne mettra pas à jour toutes les TextBox !
  If flag = 1 Then flag = 0: Exit Sub
  'sinon, c'est que flag = 0, et donc on fait le traitement habituel qui suit :
  'si la liste déroulante montre un item, mise à jour des TextBox
  If cbx1.ListIndex > -1 Then FillUF cbx1.ListIndex + 2
End Sub

Private Sub tbx0_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
  If KeyAscii = 27 Then Unload Me
End Sub

Private Sub ClrUF(k As Byte) 'sub appelée par cmdClr_Click() et par cmdAdd_Click()
  If k = 1 Then _
    If MsgBox("Voulez-vous effacer les donnée du UserForm ?", _
      4, "Confirmation") <> 6 Then Exit Sub
  Dim i As Byte     'efface toutes les cases du UF (les tbx et cbx1)
  For i = 0 To itbDE: Controls("tbx" & i) = "": Next i
  tbxDN = "": cbx1.ListIndex = -1
End Sub

Private Sub cmdClr_Click() 'bouton effacer
  ClrUF 1
End Sub

Private Sub cmdAdd_Click() 'bouton ajouter
  If tbx0 = "" Then Exit Sub 'sortie de la sub si pas de nom prénom !
  Dim cel As Range: Set cel = Ws.Columns(1).Find(tbx0, , -4163, 1, 1)
  If Not cel Is Nothing Then MsgBox tbx0 & " existe déjà !": Exit Sub
  If MsgBox("Êtes-vous certain de vouloir INSÉRER ce nouveau contact ?", _
    4, "Demande de confirmation") <> 6 Then Exit Sub
  Dim chn$, lg1&, lg2&, i As Byte, j As Byte: Application.ScreenUpdating = 0
  lg1 = cbx1.ListCount: cbx1.AddItem 'ajout d'une ligne à la liste déroulante cbx1
  cbx1.List(lg1, 0) = tbx0: cbx1.List(lg1, 1) = tbxDN 'nom prénom & date naissance
  lg1 = Ws.Cells(Rows.Count, 1).End(3).Row + 1 'dernière ligne du tableau + 1
  Ws.Cells(lg1, 1) = tbx0: Ws.Cells(lg1, colDN) = tbxDN: lg2 = lg1
  For i = 1 To itbDE 'conjoint, parents, et enfants
    chn = Controls("tbx" & i)
    If chn <> "" Then
      Set cel = Ws.Columns(1).Find(chn, , -4163, 1, 1)
      If cel Is Nothing Then
        cbx1.AddItem chn: Ws.Cells(lg1, i + 1) = chn
        lg2 = lg2 + 1: Ws.Cells(lg2, 1) = chn
        Select Case i
          Case 1: Ws.Cells(lg2, 2) = tbx0
            For j = 1 To NbEnf
              Ws.Cells(lg2, 4 + j) = Controls("tbx" & 3 + j)
            Next j
          Case 2, 3: Ws.Cells(lg2, 5) = tbx0
          Case Else
            Ws.Cells(lg2, 3) = tbx0: Ws.Cells(lg2, 4) = tbx1
        End Select
      Else
        MsgBox chn & " existe déjà !"
      End If
    End If
  Next i
  cbx1.ListIndex = -1 'pour que la liste déroulante ne montre pas d'item
  Range(Cells(lg1, 1), Cells(lg2, colDN)).Borders.LineStyle = 1 'bordures
  Application.ScreenUpdating = -1
  MsgBox "La personne présente a bien été ajoutée." 'l'ajout est confirmé
  ClrUF 2 'on efface toutes les cases du UF
End Sub

Private Sub cmdModif_Click() 'bouton modifier
  Dim k&: k = cbx1.ListIndex: If k = -1 Then Exit Sub 'On sort si pas de sélection
  If MsgBox("Êtes-vous certain de vouloir modifier les infos de cette personne ?", _
    vbYesNo, "Demande de confirmation") <> vbYes Then Exit Sub

  'mise à jour des cellules avec toutes les TextBox
  Dim lig&, i%: lig = cbx1.ListIndex + 2: Ws.Cells(lig, colDN) = tbxDN
  For i = 0 To itbDE: Ws.Cells(lig, i + 1) = Controls("tbx" & i): Next i

  'SI on a CHANGÉ tbx0, ALORS mise à jour de l'item affiché de la liste déroulante.
  'ATTENTION : si on change .List(k), il y a un appel implicite à cbx1_Change(),
  'qu'on ne peut PAS éviter, même si on désactive les évènements de l'application !
  'grâce à flag = 1, ça permettra de sortir AUSSITÔT de la sub cbx1_Change().
  With cbx1
    If .List(k) <> tbx0 Then flag = 1: .List(k) = tbx0
  End With
End Sub

Private Sub GoParent(chn$)
  Dim cel As Range: Set cel = Ws.Columns(1).Find(chn, , -4163, 1, 1)
  If Not cel Is Nothing Then cbx1.ListIndex = -1: FillUF cel.Row
End Sub

Private Sub cmdGoPère_Click() 'bouton GoPère
  Dim père$: père = tbx2: If père <> "" Then GoParent père
End Sub

Private Sub cmdGoMère_Click() 'bouton GoMère
  Dim mère$: mère = tbx3: If mère <> "" Then GoParent mère
End Sub

Private Sub cmdQuit_Click() 'bouton quitter
  Unload Me 'Unload => ferme le Userform et l'efface de la mémoire ; les valeurs de ses contrôles
  'sont à alors perdues ; Me : Référence à l'objet en cours, c'est-à-dire le formulaire UserForm1
End Sub

'Cet évènement est important car au lancement du Userform, il permet de définir les propriétés des
'objets et les valeurs par défaut des variables ; cette sub est lancée par la sub FORMULAIRE().
Private Sub UserForm_Initialize()  'initialisation de UserForm1
  Dim T, n&, i& 'ATTENTION : il ne faut PAS mettre de type pour T !
  Set Ws = Worksheets("Feuil1") 'Ws fait référence à la feuille de calcul "Feuil1"
  n = Ws.Cells(Rows.Count, 1).End(3).Row: If n = 1 Then Exit Sub
  n = n - 1: T = Ws.[A2].Resize(n, colDN)
  For i = 1 To n: T(i, 2) = T(i, colDN): Next i
  ReDim Preserve T(1 To n, 1 To 2)
  cbx1.List = T: flag = 0
End Sub

à te lire pour avoir ton avis. 😉

soan
 

Pièces jointes

  • Classeur5 test.xlsm
    37.6 KB · Affichages: 7

soan

XLDnaute Barbatruc
Inactif
Bonsoir PHV62,

voici une nouvelle version du fichier précédent.



sur le UserForm, j'ai renommé 2 boutons de commande :
cmdGoPère en GoPère et cmdGoMère en GoMère

bien sûr, la sub cmdGoPère_Click() est devenue la sub GoPère_Click()
et la sub cmdGoMère_Click() est devenue la sub GoMère_Click()

jusqu'ici, c'est rien d'autre qu'un changement de 2 noms, rien de plus.



la sub cmdGoPère() était celle-ci :

VB:
Private Sub cmdGoPère_Click() 'bouton GoPère
  Dim père$: père = tbx2: If père <> "" Then GoParent père
End Sub

j'avais mis If père<>"" Then GoParent père pour éviter d'appeler la sub GoParent() si père (= tbx2) est une chaîne de caractères vide ; mais comme dans ton fichier réel tu as de nombreux boutons de commande, c'est mieux, finalement, de déporter le test dans la sub GoParent(), ce qui va éviter de devoir mettre le test pour chaque bouton de commande qui appelle GoParent().

du coup, le nouveau code VBA est celui-ci :
VB:
Private Sub GoParent(chn$)
  If chn = "" Then Exit Sub
  Dim cel As Range: Set cel = Ws.Columns(1).Find(chn, , -4163, 1, 1)
  If Not cel Is Nothing Then cbx1.ListIndex = -1: FillUF cel.Row
End Sub

Private Sub GoPère_Click()
  GoParent tbx2  'Père
End Sub

Private Sub GoMère_Click()
  GoParent tbx3  'Mère
End Sub

ainsi, tu peux voir que les appels à la sub GoParent() sont beaucoup simplifiés !
car c'est juste GoParent tbx2 ou GoParent tbx3 ; seul le n° de tbx est modifié.



ne fais rien encore dans ton fichier réel, car je vais
t'indiquer la suite dans le prochain post. :)

soan
 

Pièces jointes

  • Classeur6 test.xlsm
    37.8 KB · Affichages: 12

PHV62

XLDnaute Junior
Bonsoir PHV62,

voici une nouvelle version du fichier précédent.



sur le UserForm, j'ai renommé 2 boutons de commande :
cmdGoPère en GoPère et cmdGoMère en GoMère

bien sûr, la sub cmdGoPère_Click() est devenue la sub GoPère_Click()
et la sub cmdGoMère_Click() est devenue la sub GoMère_Click()

jusqu'ici, c'est rien d'autre qu'un changement de 2 noms, rien de plus.



la sub cmdGoPère() était celle-ci :

VB:
Private Sub cmdGoPère_Click() 'bouton GoPère
  Dim père$: père = tbx2: If père <> "" Then GoParent père
End Sub

j'avais mis If père<>"" Then GoParent père pour éviter d'appeler la sub GoParent() si père (= tbx2) est une chaîne de caractères vide ; mais comme dans ton fichier réel tu as de nombreux boutons de commande, c'est mieux, finalement, de déporter le test dans la sub GoParent(), ce qui va éviter de devoir mettre le test pour chaque bouton de commande qui appelle GoParent().

du coup, le nouveau code VBA est celui-ci :
VB:
Private Sub GoParent(chn$)
  If chn = "" Then Exit Sub
  Dim cel As Range: Set cel = Ws.Columns(1).Find(chn, , -4163, 1, 1)
  If Not cel Is Nothing Then cbx1.ListIndex = -1: FillUF cel.Row
End Sub

Private Sub GoPère_Click()
  GoParent tbx2  'Père
End Sub

Private Sub GoMère_Click()
  GoParent tbx3  'Mère
End Sub

ainsi, tu peux voir que les appels à la sub GoParent() sont beaucoup simplifiés !
car c'est juste GoParent tbx2 ou GoParent tbx3 ; seul le n° de tbx est modifié.



ne fais rien encore dans ton fichier réel, car je vais
t'indiquer la suite dans le prochain post. :)

soan
ok merci récupéré
 

soan

XLDnaute Barbatruc
Inactif
Bonjour PHV62,

ce post est pour ton fichier réel, donc il ne sera utile que pour toi ; bien sûr, je n'ai pas joint ton fichier réel, donc les autres lecteurs peuvent s'abstenir de lire ce post (ou juste regarder les infos ci-dessous, sans pouvoir tester l'exécution de la nouvelle macro).​



sur UserForm2, liste des boutons à renommer.

dans un nom de bouton, un caractère en gras signifie juste que tu dois faire attention à taper le caractère correct (surtout si c'est « è ») ; ou ne pas l'oublier, comme « x » ou « M » !​

Partie en haut (et loin à droite)

cmdGoPère → GoPère

cmdGoMère → GoMère

Partie en bas

1
er onglet :

cmdEpou1 → GoEpoux1

cmdeEpou2 → GoEpoux2

3ème onglet :

cmdGoGPereP → GoGPèreP

cmdGoGMereP → GoGMèreP

4ème onglet :

cmdGoGPere → GoGPèreM

cmdGoGMere → GoGMèreM



voici le nouveau code VBA de la partie concernée, qui n'est bien sûr valable que si les boutons mentionnés ci-dessus ont été renommés correctement ; ATTENTION : si au-dessus tu as fait une seule petite erreur dans le nom d'un bouton, il y aura un plantage ! rappel : la sub GoParent() est à partir de la ligne n° 320 (appuie sur la touche Page Suivante pour la voir ; à partir du début du module de UserForm2, bien sûr).

VB:
Private Sub GoParent(chn$)
  If chn = "" Then Exit Sub
  Dim cel As Range, lig&, i As Byte
  Set cel = Ws.Columns(1).Find(chn, , -4163, 1, 1)
  If cel Is Nothing Then Exit Sub
  ComboBox1.ListIndex = -1: lig = cel.Row
  For i = 1 To 223
    Controls("TextBox" & i) = Ws.Cells(lig, i)
  Next i
End Sub

Private Sub GoPère_Click()
  GoParent TextBox3    'Père
End Sub

Private Sub GoMère_Click()
  GoParent TextBox4    'Mère
End Sub

Private Sub GoEpoux1_Click()
  GoParent TextBox13   'Epoux 1
End Sub

Private Sub GoEpoux2_Click()
  GoParent TextBox20   'Epoux 2
End Sub

Private Sub GoGPèreP_Click()
  GoParent TextBox99   'Grand-père P
End Sub

Private Sub GoGMèreP_Click()
  GoParent TextBox100  'Grand-mère P
End Sub

Private Sub GoGPèreM_Click()
  GoParent TextBox162  'Grand-père M
End Sub

Private Sub GoGMèreM_Click()
  GoParent TextBox163  'Grand-mère M
End Sub

à te lire pour avoir ton avis. ;)

soan
 

soan

XLDnaute Barbatruc
Inactif
Bonjour PHV62,

pas de retour ? 😭 peux-tu me dire si les nouvelles infos te conviennent ?
ne trouves-tu pas que les appels de la sub GoParent() sont simplifiés ?

est-ce que tu as pu faire les adaptations mentionnées à ton fichier réel ?
si tu as besoin d'un complément d'infos, n'hésite pas. :)

soan
 

PHV62

XLDnaute Junior
bonsoir j ai essaye mais marche pas quand je met dans fichier j ai donc garde la version précédente ou tous les boutons fonctionnent mais je vais encore faire des essais avec la version 6 mais pas facile a adapter a mon fichier
phv
 

soan

XLDnaute Barbatruc
Inactif
Bonsoir PHV62,

1) laisse inchangée la sub GoParent() ; donc elle doit être comme ça :

VB:
Private Sub GoParent(chn$)
  If chn = "" Then Exit Sub
  Dim cel As Range, lig&, i As Byte
  Set cel = Ws.Columns(1).Find(chn, , -4163, 1, 1)
  If cel Is Nothing Then Exit Sub
  ComboBox1.ListIndex = -1: lig = cel.Row
  For i = 1 To 223
    Controls("TextBox" & i) = Ws.Cells(lig, i)
  Next i
End Sub

attention : c'est à la place de la précédente sub GoParent() !



2) pour les appels, ils seront tous de ce genre :

VB:
Private Sub GoPère_Click()
  GoParent TextBox3    'Père
End Sub

donc c'est tout simple, y'a que 3 changements ; exemple pour le bouton "go mère" :

VB:
Private Sub GoMère_Click()
  GoParent TextBox4    'Mère
End Sub

a) le nom du bouton, qui est à gauche de "_Click" est maintenant GoMère
au lieu de GoPère, d'où : GoMère_Click() au lieu de GoPère_Click()

b) TextBox3 est devenu TextBox4, donc c'est bien comme je t'avais dit :
tu as juste le de la TextBox à changer ➯ le nom du TextBox doit être
celui de la personne qui est près du bouton (à gauche ou dessous)

c) le commentaire est devenu 'Mère au lieu de 'Père ; ce 3ème changement
est bien sûr facultatif, puisque les commentaires ne sont pas exécutés ;
mais c'est quand même mieux de le faire pour pouvoir mieux s'y retrouver :
quand tu lis le code VBA, tu vois plus facilement que tel bouton est pour
telle personne ; tu peux même créer ces 2 boutons :

VB:
Private Sub GoAdam_Click()
  GoParent TextBox9999999999999999999999999999991    'Adam
End Sub

Private Sub GoÈve_Click()
  GoParent TextBox9999999999999999999999999999992    'Ève
End Sub

oh ben tu vois ! on a les mêmes parents, toi et moi ! 😜 😂 🤣 c'était y'a quelques milliers de générations, à l'aube de l'Humanité : D. a séparé le Ciel et la Terre, puis dans un petit coin de Paradis appelé le Jadin d'Eden, il a créé les 2 premiers êtres humains ; tu peux prendre n'importe quel être humain sur Terre (homme ou femme), tu peux être sûr qu'il descend d'Adam et Ève ! si, si ! 🙂 c'est scientifiquement prouvé ; y'a qu'une seule personne au monde qui a osé contester cette évidence : un certain hérétique du nom de Darwin !

trêve de plaisanteries, si tu suis bien les indications de ce post, je vois pas ce qui pourrait faire que ça ne marche pas dans ton fichier réel ! pour chaque personne en plus où il faut « se rendre », il faut juste être bien attentif au nom du bouton et au numéro de la TextBox.​

soan
 
Dernière édition:

soan

XLDnaute Barbatruc
Inactif
Bonjour,

Image.jpg


PHV62 m'a écrit en MP : « merci c ok » ; en clair, ça signifie que les infos de mon post #41 lui ont permis de régler son problème : son fichier réel et confidentiel est maintenant OK ➯ ce sujet est RÉSOLU. 😊

bien sûr, j'aurais préféré que PHV62 l'indique lui-même ici, mais il a oublié et / ou il est trop occupé pour cela... :rolleyes: j'ai écrit ce post pour éviter à d'autres contributeurs de chercher inutilement une solution à un problème déjà réglé.

soan
 

Discussions similaires

Réponses
21
Affichages
340

Statistiques des forums

Discussions
312 428
Messages
2 088 333
Membres
103 815
dernier inscrit
SANOU ANSELME