XL 2021 UserForm en guise de MsgBox qui ne fonctionne pas...

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

Constantin

XLDnaute Occasionnel
Supporter XLD
Bonjour,
Dans le fichier joint, dans la feuille "départs", la macro2 chainée au bouton bleu est censée :
- Effacer dans "base de données" la ligne qui contient Nom20 Prénom Régis pour peu l'on soit positionné sur G13 dans "départs"
- Afficher un message d'information
- me repositionner dans la feuille "base de données"
Il doit y avoir un bug dans le code de macro2 car Effacer dans "base de données" la ligne qui contient Nom20 Prénom Régis ne s'exécute pas...
Il faut dire que la programmation avec UserForms n'est pas toute simple.
Si quelqu'un a une idée je suis preneur et aussi qu'il m'explique ce qui n'allait pas.
A bientôt ?
 

Pièces jointes

bonjour,
il me semble que tu essaies d'ingérer trop d'informations.

dessiner un userform c'est sommes toutes pas très compliqué il suffit avec la souris de cliker sur un contrôle et de le dimensionner sur le formulaire.

sélectionner une référence comme un WebBrowser c'est déjà plus compliqué.

de la a faire vivre ce formulaire pour en faire ce qu'on veut c'est encore autre chose.

si j'ai bien compris tu souhaites avoir une implantation qui reprend l'idée du msgbox mais un peu plus stylisé ?

déjà ton code fonctionnait il avant de tenter d'intégrer ce userform ?
 
Dernière édition:
Merci à tous,
fanfan38 ayant trouvé la solution pour l'effacement de la ligne de base de données. Par contre le MsgBox de fin d'action (quand il y a eu effacement des données) et le repositionnement sur la feuille base données ne s'exécutent plus. J'imagine que les codes du MsgBox et de l'appel de la cellule E4 dans base données ne sont pas à la bonne place.
Je joins le fichier réactualisé avec "Public rep As String"
A bientôt ?
 

Pièces jointes

Bonjour à tous,
Bon quoi dire... Quand vous travailler sur des formulaires à partir de module standards il faut passer par des propriétés. Sinon vous cassez l'encapsulation du formulaire.
Évitez aussi les variables publiques on le dit à chaque fois c'est source à problèmes, et difficilement gérable.
Troisième point votre formulaire ne doit faire qu'une chose renvoyer Vrai ou Faux exit les messages d'informations ce n'est pas son rôle. sinon vous brisez le SRP.
Quatrième point, donner des noms explicites a vos variables et procédures vous vous y retrouverez bien mieux.
Cinquième point, Toujours mettre "Otion Explicit" en tête de module. (Cela vous évitera pas mal de déconvenues.)
Partant de ces points nous pouvons modifier la classe de votre formulaire comme ceci.

VB:
Option Explicit

Private mReturnValue As VBA.VbMsgBoxResult
Private mLabelMessage As String

'// Retourne la valeur sélectionnée
Public Property Get returnValue() As VBA.VbMsgBoxResult
    returnValue = mReturnValue
End Property
Public Property Let returnValue(ByVal NewValue As VBA.VbMsgBoxResult)
    mReturnValue = NewValue
End Property

'// Met à jour le message d'information
Public Property Get LabelMessage() As String
    LabelMessage = mLabelMessage
End Property
Public Property Let LabelMessage(ByVal NewValue As String)
    Label2.Caption = NewValue
End Property

Private Sub CommandValid_Click()
    mReturnValue = vbYes
    Me.Hide '// On cache et on retourne au programme appelant.
End Sub

Private Sub CommandCancel_Click()
    mReturnValue = vbNo
    Me.Hide '// On cache et on retourne au programme appelant.
End Sub

Private Sub UserForm_Activate()
    Me.Caption = mLabelMessage
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    'vbFormControlMenu  0   L'utilisateur a choisi la commande Fermer dans le menu Système du formulaire utilisateur.
    'vbFormCode         1   L'instruction Unload est appelée à partir du code.
    'vbAppWindows       2   La session active de l'environnement d'exploitation Windows se termine.
    'vbAppTaskManager   3   Le Gestionnaire de tâches de Windows ferme l'application.
    Select Case CloseMode
        Case vbFormControlMenu
            Cancel = True
            mReturnValue = vbNo
            Me.Hide ' // On cache et on retourne au programme appelant.
    End Select
End Sub

Maintenant il reste à gérer tout cela dans votre procédure appelante (renommée en "EffacerLigneDépart")
Voici certains points à prendre en considération.
Évitez les Exit Sub, Fonction, et autres si ce n'est pas obligatoire (d'autres options s'offrent à vous.)
Regardez les commentaires pour les explications...
Code:
Sub EffacerLigneDepart()
    Call SauvegardeAutomatique '// Evitez d'utiliser Call cela ne sert que pour la les anciens codes.
 
    On Error GoTo FinR
 
    With sh_Data
 
        Dim L As Long
        L = Selection.Row                                       ' Ligne sélectionnée
     
        Dim Nom As String
        Nom = sh_Departs.Cells(L, "K")
     
        Dim Prénom As String
        Prénom = sh_Departs.Cells(L, "L")
     
        If Nom = vbNullString Or Prénom = vbNullString Then MsgBox "Sélectionnez un nom valide en colonne Nom de la feuille departs.": Exit Sub ' Verif si ligne valide
     
        With EXPORTATION
            '// On définit la propriété pour le message
            .LabelMessage = "Vous êtes sur le point d'effacer les donnée de : " & Nom & Space(1) & Prénom & vbNewLine & vbNewLine & _
                            "Voulez-Vous vraiment continuer ?"

            '// On affiche le formulaire
            .Show
            '// Sur click dans le formulaire on le cache et on arrive ici.
            Dim returnValue
            returnValue = .returnValue                          ' // On charge la valeur de retour
            Unload EXPORTATION                                  '// On ferme le formulaire
        End With
     
        Select Case returnValue                                 '// Sélection par rapporrt au choix sélectionné
            Case vbYes
                Dim DL As Long
                DL = .Cells(Rows.Count, "E").End(xlUp).Row      ' recherche dernière ligne des noms dans base de données
                Application.EnableEvents = False
                Dim Ligne As Long
                For Ligne = 4 To DL                             ' on parcourt toutes les lignes
                    If .Cells(Ligne, "E") = Nom And .Cells(Ligne, "F") = Prénom Then ' si Nom et Prénom trouvés, on efface
                        '// Ne voudrait-il pas mieux supprimer la ligne complète ?
                        .Range(.Cells(Ligne, "E"), .Cells(Ligne, "AA")).ClearContents
                    End If
                Next Ligne
            Case vbNo
                MsgBox "Action annulée par l'utilisateur", vbOKOnly, "Gestion des employés."

            Case vbCancel
                Dim problemMessage As String
                problemMessage = "Oupss... Nous avons rencontré une erreur en voulant supprimer les données de cette personne : " & _
                Nom & Space(1) & Prénom & "."
             
                MsgBox problemMessage, vbOKOnly Or vbCritical, "Gestion des employés."

        End Select
     
    End With


FinR:
    Application.EnableEvents = True
End Sub

Bonne programmation... Jean-Paul
 
Dernière édition:
Bonjour à tous,
Bon quoi dire... Quand vous travailler sur des formulaires à partir de module standards il faut passer par des propriétés. Sinon vous cassez l'encapsulation du formulaire.
Évitez aussi les variables publiques on le dit à chaque fois c'est source à problèmes, et difficilement gérable.
Troisième point votre formulaire ne doit faire qu'une chose renvoyer Vrai ou Faux exit les messages d'informations ce n'est pas son rôle. sinon vous brisez le SRP.
Quatrième point, donner des noms explicites a vos variables et procédures vous vous y retrouverez bien mieux.
Cinquième point, Toujours mettre "Otion Explicit" en tête de module. (Cela vous évitera pas mal de déconvenues.)
Partant de ces points nous pouvons modifier la classe de votre formulaire comme ceci.

VB:
Option Explicit

Private mReturnValue As VBA.VbMsgBoxResult
Private mLabelMessage As String

'// Retourne la valeur sélectionnée
Public Property Get returnValue() As VBA.VbMsgBoxResult
    returnValue = mReturnValue
End Property
Public Property Let returnValue(ByVal NewValue As VBA.VbMsgBoxResult)
    mReturnValue = NewValue
End Property

'// Met à jour le message d'information
Public Property Get LabelMessage() As String
    LabelMessage = mLabelMessage
End Property
Public Property Let LabelMessage(ByVal NewValue As String)
    Label2.Caption = NewValue
End Property

Private Sub CommandValid_Click()
    mReturnValue = vbYes
    Me.Hide '// On cache et on retourne au programme appelant.
End Sub

Private Sub CommandCancel_Click()
    mReturnValue = vbNo
    Me.Hide '// On cache et on retourne au programme appelant.
End Sub

Private Sub UserForm_Activate()
    Me.Caption = mLabelMessage
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    'vbFormControlMenu  0   L'utilisateur a choisi la commande Fermer dans le menu Système du formulaire utilisateur.
    'vbFormCode         1   L'instruction Unload est appelée à partir du code.
    'vbAppWindows       2   La session active de l'environnement d'exploitation Windows se termine.
    'vbAppTaskManager   3   Le Gestionnaire de tâches de Windows ferme l'application.
    Select Case CloseMode
        Case vbFormControlMenu
            Cancel = True
            mReturnValue = vbNo
            Me.Hide ' // On cache et on retourne au programme appelant.
    End Select
End Sub

Maintenant il reste à gérer tout cela dans votre procédure appelante (renommée en "EffacerLigneDépart")
Voici certains points à prendre en considération.
Évitez les Exit Sub, Fonction, et autres si ce n'est pas obligatoire (d'autres options s'offrent à vous.)
Regardez les commentaires pour les explications...
Code:
Sub EffacerLigneDepart()
    Call SauvegardeAutomatique '// Evitez d'utiliser Call cela ne sert que pour la les anciens codes.
 
    On Error GoTo FinR
 
    With sh_Data
 
        Dim L As Long
        L = Selection.Row                                       ' Ligne sélectionnée
    
        Dim Nom As String
        Nom = sh_Departs.Cells(L, "K")
    
        Dim Prénom As String
        Prénom = sh_Departs.Cells(L, "L")
    
        If Nom = vbNullString Or Prénom = vbNullString Then MsgBox "Sélectionnez un nom valide en colonne Nom de la feuille departs.": Exit Sub ' Verif si ligne valide
    
        With EXPORTATION
            '// On définit la propriété pour le message
            .LabelMessage = "Vous êtes sur le point d'effacer les donnée de : " & Nom & Space(1) & Prénom & vbNewLine & vbNewLine & _
                            "Voulez-Vous vraiment continuer ?"

            '// On affiche le formulaire
            .Show
            '// Sur click dans le formulaire on le cache et on arrive ici.
            Dim returnValue
            returnValue = .returnValue                          ' // On charge la valeur de retour
            Unload EXPORTATION                                  '// On ferme le formulaire
        End With
    
        Select Case returnValue                                 '// Sélection par rapporrt au choix sélectionné
            Case vbYes
                Dim DL As Long
                DL = .Cells(Rows.Count, "E").End(xlUp).Row      ' recherche dernière ligne des noms dans base de données
                Application.EnableEvents = False
                Dim Ligne As Long
                For Ligne = 4 To DL                             ' on parcourt toutes les lignes
                    If .Cells(Ligne, "E") = Nom And .Cells(Ligne, "F") = Prénom Then ' si Nom et Prénom trouvés, on efface
                        '// Ne voudrait-il pas mieux supprimer la ligne complète ?
                        .Range(.Cells(Ligne, "E"), .Cells(Ligne, "AA")).ClearContents
                    End If
                Next Ligne
            Case vbNo
                MsgBox "Action annulée par l'utilisateur", vbOKOnly, "Gestion des employés."

            Case vbCancel
                Dim problemMessage As String
                problemMessage = "Oupss... Nous avons rencontré une erreur en voulant supprimer les données de cette personne : " & _
                Nom & Space(1) & Prénom & "."
            
                MsgBox problemMessage, vbOKOnly Or vbCritical, "Gestion des employés."

        End Select
    
    End With


FinR:
    Application.EnableEvents = True
End Sub

Bonne programmation... Jean-Paul
Bonjour Jean-Paul,
Merci de vos commentaires et suggestions. Comme vous pouvez vous en rendre compte, je ne suis pas un pro d' Excel.
J'imagine que vous avez du tester vos formules sur mon fichier ? Peut-être en avez-vous gardé une copie. Si vous pouviez me l'envoyer, ce serait avec plaisir car là, je n'ai pas le niveau pour savoir ou et comment copier et remplacer tous mes codes.
Vous me dites d'éviter la fonction "Call macro"... Pourquoi ? Par quoi la remplacer (c'est quand même bien pratique)...
Je n'apprends que grâce à toutes les suggestions que le forum m'envoie,
Bien cordialement
 
Bonjour à tous,
Bon quoi dire... Quand vous travailler sur des formulaires à partir de module standards il faut passer par des propriétés. Sinon vous cassez l'encapsulation du formulaire.
Évitez aussi les variables publiques on le dit à chaque fois c'est source à problèmes, et difficilement gérable.
Troisième point votre formulaire ne doit faire qu'une chose renvoyer Vrai ou Faux exit les messages d'informations ce n'est pas son rôle. sinon vous brisez le SRP.
Quatrième point, donner des noms explicites a vos variables et procédures vous vous y retrouverez bien mieux.
Cinquième point, Toujours mettre "Otion Explicit" en tête de module. (Cela vous évitera pas mal de déconvenues.)
Partant de ces points nous pouvons modifier la classe de votre formulaire comme ceci.

VB:
Option Explicit

Private mReturnValue As VBA.VbMsgBoxResult
Private mLabelMessage As String

'// Retourne la valeur sélectionnée
Public Property Get returnValue() As VBA.VbMsgBoxResult
    returnValue = mReturnValue
End Property
Public Property Let returnValue(ByVal NewValue As VBA.VbMsgBoxResult)
    mReturnValue = NewValue
End Property

'// Met à jour le message d'information
Public Property Get LabelMessage() As String
    LabelMessage = mLabelMessage
End Property
Public Property Let LabelMessage(ByVal NewValue As String)
    Label2.Caption = NewValue
End Property

Private Sub CommandValid_Click()
    mReturnValue = vbYes
    Me.Hide '// On cache et on retourne au programme appelant.
End Sub

Private Sub CommandCancel_Click()
    mReturnValue = vbNo
    Me.Hide '// On cache et on retourne au programme appelant.
End Sub

Private Sub UserForm_Activate()
    Me.Caption = mLabelMessage
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    'vbFormControlMenu  0   L'utilisateur a choisi la commande Fermer dans le menu Système du formulaire utilisateur.
    'vbFormCode         1   L'instruction Unload est appelée à partir du code.
    'vbAppWindows       2   La session active de l'environnement d'exploitation Windows se termine.
    'vbAppTaskManager   3   Le Gestionnaire de tâches de Windows ferme l'application.
    Select Case CloseMode
        Case vbFormControlMenu
            Cancel = True
            mReturnValue = vbNo
            Me.Hide ' // On cache et on retourne au programme appelant.
    End Select
End Sub

Maintenant il reste à gérer tout cela dans votre procédure appelante (renommée en "EffacerLigneDépart")
Voici certains points à prendre en considération.
Évitez les Exit Sub, Fonction, et autres si ce n'est pas obligatoire (d'autres options s'offrent à vous.)
Regardez les commentaires pour les explications...
Code:
Sub EffacerLigneDepart()
    Call SauvegardeAutomatique '// Evitez d'utiliser Call cela ne sert que pour la les anciens codes.
 
    On Error GoTo FinR
 
    With sh_Data
 
        Dim L As Long
        L = Selection.Row                                       ' Ligne sélectionnée
    
        Dim Nom As String
        Nom = sh_Departs.Cells(L, "K")
    
        Dim Prénom As String
        Prénom = sh_Departs.Cells(L, "L")
    
        If Nom = vbNullString Or Prénom = vbNullString Then MsgBox "Sélectionnez un nom valide en colonne Nom de la feuille departs.": Exit Sub ' Verif si ligne valide
    
        With EXPORTATION
            '// On définit la propriété pour le message
            .LabelMessage = "Vous êtes sur le point d'effacer les donnée de : " & Nom & Space(1) & Prénom & vbNewLine & vbNewLine & _
                            "Voulez-Vous vraiment continuer ?"

            '// On affiche le formulaire
            .Show
            '// Sur click dans le formulaire on le cache et on arrive ici.
            Dim returnValue
            returnValue = .returnValue                          ' // On charge la valeur de retour
            Unload EXPORTATION                                  '// On ferme le formulaire
        End With
    
        Select Case returnValue                                 '// Sélection par rapporrt au choix sélectionné
            Case vbYes
                Dim DL As Long
                DL = .Cells(Rows.Count, "E").End(xlUp).Row      ' recherche dernière ligne des noms dans base de données
                Application.EnableEvents = False
                Dim Ligne As Long
                For Ligne = 4 To DL                             ' on parcourt toutes les lignes
                    If .Cells(Ligne, "E") = Nom And .Cells(Ligne, "F") = Prénom Then ' si Nom et Prénom trouvés, on efface
                        '// Ne voudrait-il pas mieux supprimer la ligne complète ?
                        .Range(.Cells(Ligne, "E"), .Cells(Ligne, "AA")).ClearContents
                    End If
                Next Ligne
            Case vbNo
                MsgBox "Action annulée par l'utilisateur", vbOKOnly, "Gestion des employés."

            Case vbCancel
                Dim problemMessage As String
                problemMessage = "Oupss... Nous avons rencontré une erreur en voulant supprimer les données de cette personne : " & _
                Nom & Space(1) & Prénom & "."
            
                MsgBox problemMessage, vbOKOnly Or vbCritical, "Gestion des employés."

        End Select
    
    End With


FinR:
    Application.EnableEvents = True
End Sub

Bonne programmation... Jean-Paul
Je précise par ailleurs que ce fichier anonymisé correspond à un programme utilisé par une association de jardiniers. Il est actuellement dépourvu de macros facilitant son exploitation et je suis chargé d'essayer de faire quelque chose. Je pars donc d'un existant dont je ne dois pas modifier la structure et la finalité (bilan de fin d'année) sauf à le rendre plus lisible et plus facile à utiliser pour des gens qui sont encore moins au fait d' Excel que moi (si c'est possible).
A bientôt ?
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Retour