Feuille userform avec paramètres

Résolu
Bonjour,

Peut-on appeler une feuille userform avec des paramètres qu'on peut traiter dans le code de la feuille ?

Merci d'avance pour vos lumières.
iBenny

9 réponses

Résumé de la discussion

Le questionnement porte sur la possibilité de passer des paramètres à un UserForm via Show ou par des propriétés afin que le code de la feuille puisse les traiter. Plusieurs réponses proposent d'utiliser des propriétés publiques sur le formulaire ou des variables publiques au niveau module pour partager les données et les traiter avant l'affichage. Des exemples concrets illustrent le passage d'informations via des propriétés (a et t), l'ouverture par MaFeuille.Show et le recours à des modules standard pour initialiser le formulaire. En cas de difficulté, l'encapsulation de l'IHM et le respect d'une séparation interface-données, ainsi que l'activation explicite dans chaque module, facilitent la réutilisation du formulaire dans d'autres classeurs.

Bobot (l’IA à votre service)
  1. Bonjour,

    Réponse à lire jusqu’à la fin :)

    Exemple simple avec un Userform nommé Questionner qui contient :
    - un Label nommé Question
    - un premier bouton nommé Bouton1
    - un second bouton nommé Bouton2

    Dans un module standard :
    Option Explicit
    Public Enum uReponse
      uBouton1 = 1
      uBouton2 = 2
    End Enum
    Sub Question_1()
      With Questionner
        .Bouton1.Caption = "Oui"
        .Bouton2.Caption = "Non"
        .Reponse = Empty
        .Question = "Remonter la dernière ligne ?"
        .Show
        If .Reponse = uBouton1 Then
          MsgBox "Reponse Oui"
        ElseIf .Reponse = uBouton2 Then
          MsgBox "Reponse Non"
        Else
          MsgBox "Pas réponse"
        End If
      End With
      Unload Questionner
    End Sub


    Dans le module du formulaire Questionner :
    Public Reponse As uReponse
    Private Sub Bouton1_Click()
      Me.Reponse = uBouton1
      Me.hide
    End Sub
    Private Sub Bouton2_Click()
      Me.Reponse = uBouton2
      Me.hide
    End Sub
    


    Le fichier : https://mon-partage.fr/f/mrGkAIjG/

    L'intérêt de cette méthode est que l'IHM est indépendante du traitement "métier".
    D'autre part, je te conseille de saisir le code manuellement, dans l'ordre ci-dessus : tu verras que l'intellisense simplifie grandement la saisie.

    0
    1. Bonjour Patrice,

      Merci beaucoup pour le concept mais il ne réponds pas à mes besoins !

      Votre solution renvoi des msgbox informant du choix de bouton pressé ce qui ne m'est d'aucune utilité. Ma solution revoie une variable booléenne vraie/faux qui m'est utile dans la poursuite du traitement de mon code (mon module comporte plus d'une centaine de procédures/fonctions étalées sur plus de 4000 lignes de code; sans compter la demi/douzaine de formes).

      Merci beaucoup de l'effort mais ma solution #27 satisfait pleinement aux besoins de mon code.

      PS: merci pour le "unload" ! je l'avais oublié celle-là ; ) Je vais l'ajouter à mon code...

      Sincère salutation Patrice,
      iBenny
      0
    2. @iBennyRe,

      Tu n'as pas compris le concept, la solution que je t'ai proposé ne renvoie pas de Msgbox, les Msgbox sont un exemple du traitement de la propriété Reponse renvoyée par le formulaire.
      Tu pourrais tout aussi bien t'en servir pour renseigner une variable booléenne que tu utiliserais par la suite.

      Quand au concept, la séparation de l'IHM et de la partie "métier", c'est un des fondamentaux de la programmation, il répond à tous les besoins.
      Un peu de lecture :
      La bonne programmation d'un userform
      Et en corrélation directe, pourquoi il faut bannir l'utilisation des variables publiques :
      Problèmes des variables publiques

      Cordialement
      0
    3. @Patrice33740Je vais lire ça quand je trouverai du temps libre. Le concept d'éviter les variables publiques pique ma curiosité. Je remarque que vous proposez des variables publiques en #28 !

      C'est quoi un IHM ? et la partie "métier" ?

      Salutations
      iBenny
      0
    4. @iBennyEn #28, c'est une Énumération (de constantes), rien à voir avec une variable !!!
      IHM : Interface Homme / Machine (dans ce cas l'userform).
      La partie "métier" du code est celle qui résout les spécificités de ton problème.

      Ceci dit, uReponse n'est là que pour simplifier le traitement de l'exemple.
      Ça amène un inconvénient majeur : l'IHM n'est plus encapsulée ! C'est donc aussi à éviter....
      Pour ça, il vaut mieux utiliser une énumération publique existante comme par exemple VbMsgBoxResult (mais avec plus de lignes de code).
      0
    5. @Patrice33740L'IMH (la forme) n'est pas encapsulée !? Ce qui veux dire ? Ce qui implique ?
      0
  2. Je fais amende honorable et donne raison à yg_be en #23 :

    On peux déclarer une variable "public" au lieu de "Dim" en global dans le module et elle serra accessible partout, même dans les formes !!!

    Quand on fait trop de choses en même temps, on s'enferre !!!

    Module:
    Public Rép As Boolean
    
    Function Question(Q As String) As Boolean
    
    With Questionner
        If Q = "Monter" Then
            .Caption = "Remonter la dernière ligne ?"
            .Sup1.Visible = False
            .Sup2.Visible = True
            .Q = "On remonte la dernière ligne ? = " + Format(Selection.Characters.Count) + " caractères"
        Else
            .Caption = "Position de l'image = " + Format(PointsToInches(Selection.Information(wdVerticalPositionRelativeToPage))) + " pouces"
        End If
        .Show
    End With
    Question = Rép
    End Function


    Forme:

    Salutation et merci à tous
    iBenny
    0
    1. Contributeur
      un autre exemple tout simple:
      code du userform
      Public Function reponse(question As String) As String
      Me.TextBox1 = question
      Me.Show
      reponse = Me.TextBox1
      End Function
      code du module:
      Sub getresp()
      Debug.Print UserForm1.reponse("dis moi")
      End Sub
      1
      1. Ne pouvant vous remercier en #23, je le fais ici ; )

        Cordiale salutation,
        iBenny
        0
    2. Y a rien à montrer. Je l'ai mis dans mon code (en jaune) de forme pour montrer ce que j'ai essayé mais vais la supprimer car inaccessible dans le module appelant. Et vice-versa...

      Salutations
      iBenny
      0
      1. Contributeur
        je n'y lis pas "public".
        et ne vois pas le versa.
        0
      2. Contributeur
        même si tu es certain d'avoir suivi les exemples et la documentation, il est très préférable de montrer l'ensemble de ce que tu essaies.
        tu nous montre vaguement du code dans le userform, sans le code correspondant dans le module.
        tu nous indiques avoir essayé l'autre méthode (vice-versa), sans montrer aucun code.

        difficile pour nous de t'indiquer où tu te trompes, si, certain d'avoir raison, tu ne nous montres rien.

        en passant, je me demande si tu as bien
        option explicit
        dans chaque module et userform.
        cela te permettrait, sans doute, de détecter plus rapidement tes erreurs.
        0
    3. Bonjour

      Le problème insoluble réside dans le fait qu'une variable globale définie dans le module appelant n'est pas accessible dans la forme appelée... et vice versa (à ce que je comprends).

      Ma variable globale Rép dans la forme est invisible dans le module appelant.

      J'ai contourné le problème en sauvegardant la valeur convoitée dans la propriété "Tag" de la forme qui elle est accessible dans le module appelant. Le tour est joué :
      Function Question(Q As String)
      
      With Questionner
          If Q = "Monter" Then
              .Caption = "Remonter la dernière ligne ?"
              .Sup1.Visible = False
              .Sup2.Visible = True
              .Q = "On remonte la dernière ligne ? = " + Format(Selection.Characters.Count) + " caractères"
          Else
              .Caption = "Position de l'image = " + Format(PointsToInches(Selection.Information(wdVerticalPositionRelativeToPage))) + " pouces"
          End If
          .Show
      End With
      Question = Questionner.Tag
      End Function


      Si vous avez des infos sur la communication de variables globales entre module appelant et forme appelée, on est intéressé par la chose. Entretemps. passer par la propriété "Tag" semble une élégante solution.

      Cordiales salutations
      iBenny
      0
      1. Contributeur
        tu ne nous montres pas comment tu as fait avec les variables "globales".
        0
      2. Contributeur
        @yg_becomme expliqué en #9:
        - une variable déclarée public dans un module est accessible, comme une variable, de partout
        - une variable déclarée public dans un userform est une propriété publique du userform, utilisable exactement comme tu utilises les autres propriétés du userform, telles que Tag, Caption et Q, donc ainsi:
        Questionner.Rép
        0
      3. @yg_beJ'ai dû mal lire. Je reteste...
        0
      4. @yg_beJe suis pas certain de te comprendre :

        Je viens de tester et une variable déclarée globale au niveau module est... "invisible" dans les formes appelées !

        On ne déclare pas une variable en tant que "Public" mais elle le deviens quand elle est déclarée niveau module. C'est probablement ce que tu voulais dire !?

        Salutation
        iBenny
        0
      5. Contributeur
        @iBennytu écris "On ne déclare pas une variable en tant que "Public"".
        d'où cela vient-il? une conviction personnelle?

        as-tu vu les exemples en #6?
        pourquoi ne pas utiliser ces exemples, en dépit de tes convictions?
        au minimum, les tester, avant de décider de faire autrement?
        ne fût-ce que par respect pour ceux qui prennent le temps de t'assister.

        tu me sembles plus prompt à poser des questions qu'à lire les réponses.
        cela pourrait finir par décourager ceux qui choisissent de te donner un coup de main.
        0
    4. Re,

      Pour remplacer le MsgBox, tu peux utiliser le MsgBox Perso de Didier Fourgeot, déjà fait et entièrement paramétrable :
      http://www.mdf-xlpages.com/modules/TDMDownloads/singlefile.php?lid=34&com_id=449&com_rootid=449&cid=10&amp

      0
      1. Merci Patrice pour l'info. Je préfère continuer avec ma forme personnelle qui est en voie de perfectionnement ! et elle marche bien mais la passation d'information d'info (variable) reste à développer.
        0
    5. Bonjour,

      « Une feuille nommée MaFeuille peut être invoqué dans le code par son nom : MaFeuille.show
      Est-il possible de passer des paramètres à la feuille d'une façon quelconque ? »


      Il n'est pas possible de transmettre des informations à un Userform via les arguments (on utilise argument plutôt que « paramètre ») de la méthode .Show.

      L'ouverture d'un Userform se fait par la méthode .Show qui possède un argument facultatif DoModal. C'est le seul argument toléré par la méthode .Show

      Pour transmettre des information à un Userform, il est possible de définir des propriétés. Il suffit d'affecter leurs valeurs à ces propriétés avant d'afficher l'Userform.
      C'est ce qui devrait être fait systématiquement pour séparer l'interface utilisateur et les données "métier".
      Pour définir une propriété d'un userform, on peut simplement déclarer une variable publique dans cet userform.

      Par Exemple :
      Un bouton dans ThisDocument :
      Private Sub MonBouton_Click()
      Dim bit As Byte
      Dim str As String
        bit = 23
        str = "Mon texte"
        MonModule.OuvrirMaFeuille bit, str
      End Sub

      Et une procédure d'affichage dans un module standard nommé MonModule :
      Sub OuvrirMaFeuille(b As Byte, s As String)
        MaFeuille.a = b
        MaFeuille.t = s
        MaFeuille.Show
      End Sub
      

      Et finalement le Userform nommé MaFeuille :
      Public a As Byte
      Public t As String
      Private Sub btnAfficher_Click()
        MsgBox "Propriété a = " & Me.a & vbCrLf & _
               "Propriété t = " & Me.t
      End Sub
      Private Sub btnQuitter_Click()
        Unload Me
      End Sub


      Le fichier : https://mon-partage.fr/f/jKMDFTmH/

      Cordialement
      Patrice

      Personne ne peut détenir tout le savoir, c'est pour ça qu'on le partage.
      1
      1. MERCI Patrice pour ton commentaire final !

        Arguments, en effet !

        CONFUSION : si j'utilise le terme "Feuille", c'est pcq WORD VBA l'utilise dans l'aide du Visual Basic intégré. Ne PAS confondre avec feuille... "de calcul" dans Excel ! Désolé pour la confusion...

        Patrice a bien saisi l'essence de ma question : je devrai finalement créer des variables globales soit dans :

        1- le module principal NewMacro, les définir avant l'affichage de la "fenêtre" et les manipuler dans la "fenêtre" (UserForm);

        2- le code de la "fenêtre" (UserForm) et les pré-définir dans la procédure d'appel de NewMacro avant d'afficher la fenêtre.

        Pourquoi cet exercice ? Pcq je veux remplacer l'objet MsgBox avec une fenêtre prédéfinie car de cette façon, je peux modifier la police du texte du message, ce qu'on ne peux pas faire dans un MsgBox. Je veux donc prédéfinir les textes de l'en-tête et du "message" et les incorporer dans la forme en guise de question, ajouter deux boutons Oui/Non et traiter la suite du code en fonction de la réponse sélectionnée.

        Merci Patrice...

        Salutation cordiale à tous,
        iBenny
        0
      2. Contributeur
        @iBennypeux-tu alors marquer la discussion comme résolue?
        0
      3. @iBennyAttention, les variables "publiques" définies dans un Userform ne sont pas des véritables variables publiques : ce sont des propriétés de l'Userform . Elles ne sont pas directement utilisables dans les modules standards ou dans les autres modules objets d'Excel.

        Par contre je déconseille toujours très vivement l'utilisation de variables publiques (i.e. définies dans un module standard). Il vaut mieux transférer les informations via les arguments des procédures et / ou des fonctions .
        0
      4. Contributeur
        @iBennytu peux parfaitement travailler sans variable globale, soit en manipulant la forme dans ton code principal:
        Sub updtxt2()
        UserForm1.TextBox1 = "coucoucoucou"
        UserForm1.TextBox1.FontName = "arial"
        UserForm1.TextBox1.FontSize = 20
        UserForm1.Show
        End Sub


        soit en passant des paramètres à une fonction de la userform:
        le code de la userform:
        Public Function chgtextbox(texte As String)
        Me.TextBox1 = texte
        End Function

        le code principal:
        Private Sub updtxt()
        UserForm1.chgtextbox ("coucou toi")
        UserForm1.Show
        End Sub
        0
      5. @yg_beBonjour yg_be,

        Une fonction publique d'un Userform s'appelle une méthode.
        - Les méthodes servent à effectuer des actions,
        - Les propriétés servent à stocker des données.
        0
    6. Contributeur
      en essayant de donner un sens à ce que écris, je me demande si tu ne fais pas ceci:
      - tu fais du VBA dans Word,
      - dans ce VBA, tu interagis avec Excel, et tu appliques la méthode show à un object de type (Excel)UserForm.
      - tu souhaites que le VBA de Word puisse communiquer des données qui seraient utilisées par du code VBA dans Excel

      est-ce correct?
      si oui, peux-tu nous montrer ce que tu fais en VBA dans Word, pour interagir avec Excel? il me semble probable qu'il soit possible d'adapter cela pour obtenir ce que tu souhaites.
      0
      1. Contributeur
        bonjour,
        utilises-tu Excel?

        ta question est peu claire: que veux-tu dire par "appeler une feuille userform"?
        que sont les paramètres d'une feuille ou d'une userform?

        il est probablement préférable que tu expliques ce que tu veux réaliser, peut-être en donnant un exemple ou en partageant un fichier.
        0
        1. Bonjour,

          Dans Word ! Une procédure peut être appelée avec des paramètres quand elle est conçue ainsi:

          Sub LetsGo(a as byte, t as string)
          ...
          end Sub

          On peut donc appeler la procédure avec des paramètres:
          LetsGo 23, "Mon texte"

          Une feuille nommée MaFeuille peut être invoqué dans le code par son nom :
          MaFeuille.show

          Est-il possible de passer des paramètres à la feuille d'une façon quelconque ?
          0
        2. Contributeur
          @iBennyune feuille dans Word? peux-tu expliquer? qu'est MaFeuille? quel est le type de MaFeuille?

          tu peux peut-être consulter la documentation relative à ce type d'objet pour déterminer si la méthode show accepte des paramètres.

          il est probablement préférable que tu expliques ce que tu veux réaliser, peut-être en donnant un exemple ou en partageant un fichier. cela nous permettra peut-être de suggérer des solutions.
          0