Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Simplifier une procédure : 1 seule fois pour toutes ?

5 réponses
Avatar
Florian
Bonjour
J'ai cette procédure qui fonctionne très bien, dans ce cas là.
J'ai sur le userform 2 textbox et un frame à faire clignoter.
Mais dans le cas ou j'ai une vingtaine de contrôles ou plus ?
A-t'on la possibilité d'éviter de signifier à chaque fois le contrôle que
l'on doit faire clignoter ceci pour ne pas mettre :
derrière chaque contrôle le même type de procédure?
Merci beaucoup
Flo riant

Private Declare Function GetTickCount Lib "Kernel32" () As Long

Private Sub CommandButton1_Click()
Dim I As Integer
If TextBox1 = "" Then
MsgBox "Vous devez saisir un nom," & vbNewLine & _
"sinon vous ne pouvez pas valider la saisie.", vbExclamation, _
" Nom ?"
TextBox1.SetFocus
Do While I < 3
TextBox1.BackColor = vbRed
Label1.Visible = False
Minuterie 250
Label1.Visible = True
TextBox1.BackColor = vbWhite
Minuterie 250
I = I + 1
Loop
Exit Sub
End If

If TextBox2 = "" Then
MsgBox "Vous devez saisir un prénom," & vbNewLine & _
"sinon vous ne pouvez pas valider la saisie.", vbExclamation, _
" Prénom ?"
TextBox2.SetFocus
Do While I < 3
TextBox2.BackColor = vbRed
Minuterie 250
TextBox2.BackColor = vbWhite
Minuterie 250
I = I + 1
Loop
Exit Sub
End If

'Choix
If OptionButton1 = False And OptionButton2 = False Then
MsgBox "Vous devez choisir soit ""Suspension"", soit ""Reprise""," &
vbNewLine & _
"sinon vous ne pouvez pas valider la saisie.", vbExclamation, _
" Suspension ou Reprise ?"
Do While I < 3
Frame1.BackColor = vbRed
Minuterie 250
Frame1.BackColor = &H80FFFF
Minuterie 250
I = I + 1
Loop
Exit Sub
End If
End Sub

Sub Minuterie(Milliseconde As Long)
Dim Arret As Long
Arret = GetTickCount() + Milliseconde
Do While GetTickCount() < Arret
DoEvents
Loop
End Sub

5 réponses

Avatar
Jacques93
Bonjour Florian,

Sub Clignote(Ctrl As Control, BackColor1 As Long, _
BackColor2 As Long, Optional lbl = Nothing)
Dim i As Integer
Dim SaveColor As Long

Ctrl.SetFocus
SaveColor = Ctrl.BackColor
Do While i < 3
Ctrl.BackColor = BackColor1
If Not lbl Is Nothing Then lbl.Visible = False
Minuterie 250
If Not lbl Is Nothing Then lbl.Visible = True
Ctrl.BackColor = BackColor2
Minuterie 250
i = i + 1
Loop
Ctrl.BackColor = SaveColor
End Sub

A appeler avec :

Clignote TextBox1, vbRed, vbWhite, Label1
Clignote TextBox2, vbRed, vbWhite
Clignote Frame1, vbRed, &H80FFFF

NB: Pour les OptionButton, en général on en un positionne un à True
(Celui qui est censé representer la valeur par défaut). Ensuite il y
en aura toujours un de sélectionné, et le test n'est plus nécessaire.

Bonjour
J'ai cette procédure qui fonctionne très bien, dans ce cas là.
J'ai sur le userform 2 textbox et un frame à faire clignoter.
Mais dans le cas ou j'ai une vingtaine de contrôles ou plus ?
A-t'on la possibilité d'éviter de signifier à chaque fois le contrôle que
l'on doit faire clignoter ceci pour ne pas mettre :
derrière chaque contrôle le même type de procédure?
Merci beaucoup
Flo riant

Private Declare Function GetTickCount Lib "Kernel32" () As Long

Private Sub CommandButton1_Click()
Dim I As Integer
If TextBox1 = "" Then
MsgBox "Vous devez saisir un nom," & vbNewLine & _
"sinon vous ne pouvez pas valider la saisie.", vbExclamation, _
" Nom ?"
TextBox1.SetFocus
Do While I < 3
TextBox1.BackColor = vbRed
Label1.Visible = False
Minuterie 250
Label1.Visible = True
TextBox1.BackColor = vbWhite
Minuterie 250
I = I + 1
Loop
Exit Sub
End If

If TextBox2 = "" Then
MsgBox "Vous devez saisir un prénom," & vbNewLine & _
"sinon vous ne pouvez pas valider la saisie.", vbExclamation, _
" Prénom ?"
TextBox2.SetFocus
Do While I < 3
TextBox2.BackColor = vbRed
Minuterie 250
TextBox2.BackColor = vbWhite
Minuterie 250
I = I + 1
Loop
Exit Sub
End If

'Choix
If OptionButton1 = False And OptionButton2 = False Then
MsgBox "Vous devez choisir soit ""Suspension"", soit ""Reprise""," &
vbNewLine & _
"sinon vous ne pouvez pas valider la saisie.", vbExclamation, _
" Suspension ou Reprise ?"
Do While I < 3
Frame1.BackColor = vbRed
Minuterie 250
Frame1.BackColor = &H80FFFF
Minuterie 250
I = I + 1
Loop
Exit Sub
End If
End Sub

Sub Minuterie(Milliseconde As Long)
Dim Arret As Long
Arret = GetTickCount() + Milliseconde
Do While GetTickCount() < Arret
DoEvents
Loop
End Sub





--
Cordialement,

Jacques.

Avatar
Florian
Bravo et merci beaucoup Jacques93
Concernant les optionbutton, le pb est que si il y en a 1 par défaut,
l'utilisateur ne fera pas forcément attention :
Exemple un optionbutton Homme et un optionbutton Femme
Si il est sur Homme par défaut l'utilisateur va automatiquement valider sans
faire attention, alors que là, il sera obligé de faire un choix cohérent,
non ?
Flo riant

"Jacques93" a écrit dans le message de
news:
Bonjour Florian,

Sub Clignote(Ctrl As Control, BackColor1 As Long, _
BackColor2 As Long, Optional lbl = Nothing)
Dim i As Integer
Dim SaveColor As Long

Ctrl.SetFocus
SaveColor = Ctrl.BackColor
Do While i < 3
Ctrl.BackColor = BackColor1
If Not lbl Is Nothing Then lbl.Visible = False
Minuterie 250
If Not lbl Is Nothing Then lbl.Visible = True
Ctrl.BackColor = BackColor2
Minuterie 250
i = i + 1
Loop
Ctrl.BackColor = SaveColor
End Sub

A appeler avec :

Clignote TextBox1, vbRed, vbWhite, Label1
Clignote TextBox2, vbRed, vbWhite
Clignote Frame1, vbRed, &H80FFFF

NB: Pour les OptionButton, en général on en un positionne un à True (Celui
qui est censé representer la valeur par défaut). Ensuite il y
en aura toujours un de sélectionné, et le test n'est plus nécessaire.

Bonjour
J'ai cette procédure qui fonctionne très bien, dans ce cas là.
J'ai sur le userform 2 textbox et un frame à faire clignoter.
Mais dans le cas ou j'ai une vingtaine de contrôles ou plus ?
A-t'on la possibilité d'éviter de signifier à chaque fois le contrôle que
l'on doit faire clignoter ceci pour ne pas mettre :
derrière chaque contrôle le même type de procédure?
Merci beaucoup
Flo riant

Private Declare Function GetTickCount Lib "Kernel32" () As Long

Private Sub CommandButton1_Click()
Dim I As Integer
If TextBox1 = "" Then
MsgBox "Vous devez saisir un nom," & vbNewLine & _
"sinon vous ne pouvez pas valider la saisie.", vbExclamation, _
" Nom ?"
TextBox1.SetFocus
Do While I < 3
TextBox1.BackColor = vbRed
Label1.Visible = False
Minuterie 250
Label1.Visible = True
TextBox1.BackColor = vbWhite
Minuterie 250
I = I + 1
Loop
Exit Sub
End If

If TextBox2 = "" Then
MsgBox "Vous devez saisir un prénom," & vbNewLine & _
"sinon vous ne pouvez pas valider la saisie.", vbExclamation, _
" Prénom ?"
TextBox2.SetFocus
Do While I < 3
TextBox2.BackColor = vbRed
Minuterie 250
TextBox2.BackColor = vbWhite
Minuterie 250
I = I + 1
Loop
Exit Sub
End If

'Choix
If OptionButton1 = False And OptionButton2 = False Then
MsgBox "Vous devez choisir soit ""Suspension"", soit ""Reprise""," &
vbNewLine & _
"sinon vous ne pouvez pas valider la saisie.", vbExclamation, _
" Suspension ou Reprise ?"
Do While I < 3
Frame1.BackColor = vbRed
Minuterie 250
Frame1.BackColor = &H80FFFF
Minuterie 250
I = I + 1
Loop
Exit Sub
End If
End Sub

Sub Minuterie(Milliseconde As Long)
Dim Arret As Long
Arret = GetTickCount() + Milliseconde
Do While GetTickCount() < Arret
DoEvents
Loop
End Sub



--
Cordialement,

Jacques.



Avatar
Jacques93
Bonjour Florian,

Effectivement, je ne faisais que rappeler le fonctionnement
'standard', et il existe des cas où il faut l'éviter.

[...]
Concernant les optionbutton, le pb est que si il y en a 1 par défaut,
l'utilisateur ne fera pas forcément attention :
Exemple un optionbutton Homme et un optionbutton Femme
Si il est sur Homme par défaut l'utilisateur va automatiquement valider sans
faire attention, alors que là, il sera obligé de faire un choix cohérent,
non ?
Flo riant



--
Cordialement,

Jacques.

Avatar
Hervé
Bonjour Florian,
Une autre façon, utiliser un tableau (tu pourrais même passer par un module
de classe). Je pense, mais ceci n'engage que moi, que pour une meilleure
maintenance du code, tu devrais éviter de tout mettre dans la même proc, il
vaux mieux scinder, donc ta proc principale sur l'événement Clic du bouton
et la partie clignotement et minuterie à part. Enfin tu vois ce qui te
conviens le mieux. Le petit problème avec ta procédure c'est, d'une part ton
message, qui doit être construit en fonction du TextBox et d'autre part tes
Labels. Je pense que si tu fait déjà clignoter le TextBox vide, cela attire
suffisamment l'attention de l'utilisateur, le Label est superflu. Pour
simplifier la proc, tu pourrais faire un message plus généraliste mais tout
aussi parlant, ce qui raccourcirait le code ci-dessous. Enfin, je te donne
simplement mon avis qui est probablement différent de celui d'autres
intervenants de ce forum.
PS dans mon exemple, les TextBox se nomment "nom", "prénom", "age", "lieu"
et "code_postal" (d'où : "Replace(Tbl(I).Name, "_", " ")" ). Adapte.

Private Declare Function GetTickCount Lib "Kernel32" () As Long

Private Sub CommandButton1_Click()
Dim Tbl() As MSForms.TextBox
Dim Message As String
Dim Erreur As Boolean
Dim I As Integer
Dim J As Integer

For I = 0 To Me.Controls.Count - 1
If TypeName(Me.Controls(I)) = "TextBox" Then
J = J + 1
ReDim Preserve Tbl(1 To J)
Set Tbl(J) = Me.Controls(I)
End If
Next I

'à supprimer pour proc plus courte
'et plus générale (For I à Next I ainsi que
'tout se qui conserne Message)
Message = "Vous devez saisir un "
For I = 1 To UBound(Tbl)
If Tbl(I).Text = "" Then
Select Case Tbl(I).Name
Case "nom"
Message = Message & "nom,"
Erreur = True
Exit For
Case "prénom"
Message = Message & "prénom,"
Erreur = True
Exit For
Case "age"
Message = Message & "age,"
Erreur = True
Exit For
Case "lieu"
Message = Message & "lieu,"
Erreur = True
Exit For
Case "code_postal"
Message = Message & "code postal,"
Erreur = True
Exit For
End Select
End If
Next I

'à conserver pour proc plus courte
'et plus générale (ôter les apostrophes)
'''For I = 1 To UBound(Tbl)
''' If Tbl(I).Text = "" Then
''' MsgBox "veuillez renseigner tous les champs !", _
''' vbExclamation, "Champs vides interdits !"
''' Clignote Tbl(I)
''' Exit For
''' End If
'''Next I

'à supprimer pour proc plus courte
'et plus générale (If à End if)
If Erreur = True Then
Message = Message & vbNewLine _
& "sinon vous ne pouvez pas valider la saisie."
MsgBox Message, vbExclamation, Replace(Tbl(I).Name, "_", " ")
Clignote Tbl(I)
End If

Erase Tbl
End Sub

Sub Clignote(CtrlTxt As MSForms.TextBox)
Dim I As Integer
CtrlTxt.SetFocus
Do While I < 3
CtrlTxt.BackColor = vbRed
Minuterie 250
CtrlTxt.BackColor = vbWhite
Minuterie 250
I = I + 1
Loop
End Sub

Sub Minuterie(Milliseconde As Long)
Dim Arret As Long
Arret = GetTickCount() + Milliseconde
Do While GetTickCount() < Arret
DoEvents
Loop
End Sub

Hervé.

"Florian" a écrit dans le message news:

Bonjour
J'ai cette procédure qui fonctionne très bien, dans ce cas là.
J'ai sur le userform 2 textbox et un frame à faire clignoter.
Mais dans le cas ou j'ai une vingtaine de contrôles ou plus ?
A-t'on la possibilité d'éviter de signifier à chaque fois le contrôle que
l'on doit faire clignoter ceci pour ne pas mettre :
derrière chaque contrôle le même type de procédure?
Merci beaucoup
Flo riant

Private Declare Function GetTickCount Lib "Kernel32" () As Long

Private Sub CommandButton1_Click()
Dim I As Integer
If TextBox1 = "" Then
MsgBox "Vous devez saisir un nom," & vbNewLine & _
"sinon vous ne pouvez pas valider la saisie.", vbExclamation, _
" Nom ?"
TextBox1.SetFocus
Do While I < 3
TextBox1.BackColor = vbRed
Label1.Visible = False
Minuterie 250
Label1.Visible = True
TextBox1.BackColor = vbWhite
Minuterie 250
I = I + 1
Loop
Exit Sub
End If

If TextBox2 = "" Then
MsgBox "Vous devez saisir un prénom," & vbNewLine & _
"sinon vous ne pouvez pas valider la saisie.", vbExclamation, _
" Prénom ?"
TextBox2.SetFocus
Do While I < 3
TextBox2.BackColor = vbRed
Minuterie 250
TextBox2.BackColor = vbWhite
Minuterie 250
I = I + 1
Loop
Exit Sub
End If

'Choix
If OptionButton1 = False And OptionButton2 = False Then
MsgBox "Vous devez choisir soit ""Suspension"", soit ""Reprise""," &
vbNewLine & _
"sinon vous ne pouvez pas valider la saisie.", vbExclamation, _
" Suspension ou Reprise ?"
Do While I < 3
Frame1.BackColor = vbRed
Minuterie 250
Frame1.BackColor = &H80FFFF
Minuterie 250
I = I + 1
Loop
Exit Sub
End If
End Sub

Sub Minuterie(Milliseconde As Long)
Dim Arret As Long
Arret = GetTickCount() + Milliseconde
Do While GetTickCount() < Arret
DoEvents
Loop
End Sub




Avatar
Florian
Bonjour Hervé,
Mais elle est géniale cette procédure et très complète en plus ;-)
Je te remercie grandement
et te souhaite une très bonne soirée
Flo riant

"Hervé" a écrit dans le message de news:

Bonjour Florian,
Une autre façon, utiliser un tableau (tu pourrais même passer par un
module
de classe). Je pense, mais ceci n'engage que moi, que pour une meilleure
maintenance du code, tu devrais éviter de tout mettre dans la même proc,
il
vaux mieux scinder, donc ta proc principale sur l'événement Clic du bouton
et la partie clignotement et minuterie à part. Enfin tu vois ce qui te
conviens le mieux. Le petit problème avec ta procédure c'est, d'une part
ton
message, qui doit être construit en fonction du TextBox et d'autre part
tes
Labels. Je pense que si tu fait déjà clignoter le TextBox vide, cela
attire
suffisamment l'attention de l'utilisateur, le Label est superflu. Pour
simplifier la proc, tu pourrais faire un message plus généraliste mais
tout
aussi parlant, ce qui raccourcirait le code ci-dessous. Enfin, je te donne
simplement mon avis qui est probablement différent de celui d'autres
intervenants de ce forum.
PS dans mon exemple, les TextBox se nomment "nom", "prénom", "age", "lieu"
et "code_postal" (d'où : "Replace(Tbl(I).Name, "_", " ")" ). Adapte.

Private Declare Function GetTickCount Lib "Kernel32" () As Long

Private Sub CommandButton1_Click()
Dim Tbl() As MSForms.TextBox
Dim Message As String
Dim Erreur As Boolean
Dim I As Integer
Dim J As Integer

For I = 0 To Me.Controls.Count - 1
If TypeName(Me.Controls(I)) = "TextBox" Then
J = J + 1
ReDim Preserve Tbl(1 To J)
Set Tbl(J) = Me.Controls(I)
End If
Next I

'à supprimer pour proc plus courte
'et plus générale (For I à Next I ainsi que
'tout se qui conserne Message)
Message = "Vous devez saisir un "
For I = 1 To UBound(Tbl)
If Tbl(I).Text = "" Then
Select Case Tbl(I).Name
Case "nom"
Message = Message & "nom,"
Erreur = True
Exit For
Case "prénom"
Message = Message & "prénom,"
Erreur = True
Exit For
Case "age"
Message = Message & "age,"
Erreur = True
Exit For
Case "lieu"
Message = Message & "lieu,"
Erreur = True
Exit For
Case "code_postal"
Message = Message & "code postal,"
Erreur = True
Exit For
End Select
End If
Next I

'à conserver pour proc plus courte
'et plus générale (ôter les apostrophes)
'''For I = 1 To UBound(Tbl)
''' If Tbl(I).Text = "" Then
''' MsgBox "veuillez renseigner tous les champs !", _
''' vbExclamation, "Champs vides interdits !"
''' Clignote Tbl(I)
''' Exit For
''' End If
'''Next I

'à supprimer pour proc plus courte
'et plus générale (If à End if)
If Erreur = True Then
Message = Message & vbNewLine _
& "sinon vous ne pouvez pas valider la saisie."
MsgBox Message, vbExclamation, Replace(Tbl(I).Name, "_", " ")
Clignote Tbl(I)
End If

Erase Tbl
End Sub

Sub Clignote(CtrlTxt As MSForms.TextBox)
Dim I As Integer
CtrlTxt.SetFocus
Do While I < 3
CtrlTxt.BackColor = vbRed
Minuterie 250
CtrlTxt.BackColor = vbWhite
Minuterie 250
I = I + 1
Loop
End Sub

Sub Minuterie(Milliseconde As Long)
Dim Arret As Long
Arret = GetTickCount() + Milliseconde
Do While GetTickCount() < Arret
DoEvents
Loop
End Sub

Hervé.

"Florian" a écrit dans le message news:

Bonjour
J'ai cette procédure qui fonctionne très bien, dans ce cas là.
J'ai sur le userform 2 textbox et un frame à faire clignoter.
Mais dans le cas ou j'ai une vingtaine de contrôles ou plus ?
A-t'on la possibilité d'éviter de signifier à chaque fois le contrôle que
l'on doit faire clignoter ceci pour ne pas mettre :
derrière chaque contrôle le même type de procédure?
Merci beaucoup
Flo riant

Private Declare Function GetTickCount Lib "Kernel32" () As Long

Private Sub CommandButton1_Click()
Dim I As Integer
If TextBox1 = "" Then
MsgBox "Vous devez saisir un nom," & vbNewLine & _
"sinon vous ne pouvez pas valider la saisie.", vbExclamation, _
" Nom ?"
TextBox1.SetFocus
Do While I < 3
TextBox1.BackColor = vbRed
Label1.Visible = False
Minuterie 250
Label1.Visible = True
TextBox1.BackColor = vbWhite
Minuterie 250
I = I + 1
Loop
Exit Sub
End If

If TextBox2 = "" Then
MsgBox "Vous devez saisir un prénom," & vbNewLine & _
"sinon vous ne pouvez pas valider la saisie.", vbExclamation, _
" Prénom ?"
TextBox2.SetFocus
Do While I < 3
TextBox2.BackColor = vbRed
Minuterie 250
TextBox2.BackColor = vbWhite
Minuterie 250
I = I + 1
Loop
Exit Sub
End If

'Choix
If OptionButton1 = False And OptionButton2 = False Then
MsgBox "Vous devez choisir soit ""Suspension"", soit ""Reprise""," &
vbNewLine & _
"sinon vous ne pouvez pas valider la saisie.", vbExclamation, _
" Suspension ou Reprise ?"
Do While I < 3
Frame1.BackColor = vbRed
Minuterie 250
Frame1.BackColor = &H80FFFF
Minuterie 250
I = I + 1
Loop
Exit Sub
End If
End Sub

Sub Minuterie(Milliseconde As Long)
Dim Arret As Long
Arret = GetTickCount() + Milliseconde
Do While GetTickCount() < Arret
DoEvents
Loop
End Sub