Différents problèmes d'UserForm

Bonjour,

Je suis nouveau sur le forum et je viens (comme beaucoup je pense) parce que je suis bloqué sur vba ^^

J'ai réalisé un document permettant de proposer des quizz aux utilisateurs. Il fonctionne très bien mais pour des raisons esthétiques, je souhaite remplacer les msgbox par des userform. Petit problème, je ne maitrise pas bien cette fonctionnalité et bien qu'avec les nombreux tuto présent sur internet (je mettrais bien les liens consultés mais je voudrais pas que cela passe pour de la pub), je me retrouve confronté à quelques problèmes.

(voir Userform -> "FenetreQuizz4")

1 - Tout d'abord, le principal je pense : Comment faire entrer des variables dans l'userform_initialize ?

2 - Là le problème est assez facilement contournable mais j'aimerais bien le faire de cette façon si c'est possible : Comment conserver dans un variable des valeurs obtenu après un Call sans avoir à les écrire sur une feuille et les récupérer ensuite.

'sinon je peux juste faire quelque chose dans le genre mais ça fait un peu bricole ^^

private sub ctrl_click ()

dim a as string

range("A1")="test"

end sub

Sub test()

dim résultat as string

résultat = cells(1,1).value

msgbox résultat

end sub
'je préfèrerais quelque chose dans ce genre

Sub test()

dim résultat as string

userform.show (résultat as string) 'récupération directe de la valeur de "résultat" par l'appel de l'userform

msgbox résultat

end sub

Mais n'y a t'il pas de moyen pour récupérer "résultat" directement depuis la macro lancée "ctrl_click" ?

(Voir "FenetreQuizz2")

3 - J'ai du mal à définir des contrôles à l'aide de nom contenus dans une variable (j'en ai besoin pour intégrer le nom des CheckBox dans une boucle selon leur nombre)

Il s'agit surement de manque de connaissance vis à vis du fonctionnement des UserForm mais c'est la première fonctionnalité d'Excel sur laquelle j'ai autant de mal ^^ J'espère que vous pourrez m'aider avec ces différents problèmes.

Je vous remercie par avance pour le temps que vous passerez sur mon problème.

Cordialement,

Lorwin

19bug.xlsm (22.70 Ko)

Salut,

Tu peux déclarer des variables globales qui sont utilisable/visible dans tous ton fichier en déclarant en premier ligne de module du genre :

Public RESULTAT As String

Sub toto()
RESULTAT = 2
Call AJOUTE
MsgBox RESULTAT
End Sub

Sub AJOUTE()
RESULTAT = RESULTAT + 2
End Sub

si tu lance toto, résultat vaudra 4,

Il y a aussi d'autre chose utile pour faire avec un autre moyen un peu ce dont tu parles, les Fonctions qui peuvent renvoyer des valeurs, par exemple sans utiliser de variables public:

Sub toto()
Dim CHIFFRE As Integer
Dim RESULTAT As Integer
CHIFFRE = 2

RESULTAT = AJOUTE_UN(CHIFFRE)
MsgBox "chiffre vaut: " & CHIFFRE
MsgBox "le resultat vaut:" & RESULTAT

End Sub

Function AJOUTE_UN(NOMBRE As Integer) As Integer
AJOUTE_UN = NOMBRE + 1
End Function

Pour faire simple, ici on a une fonction qui ajoute 1, pour ce faire elle attend une variable de type integer que j'appelle NOMBRE (arbitrairement fixé par moi, cette variable existe que dans la fonction) et je déclare que ma fonction est elle même de type Integer

Du coup on peut affecter à la function elle même une valeur, qui est automatiquement renvoyer en fin de fonction après le End Function; ici je lui donc que

ma fonction vaut NOMBRE (qu'on me donne en entrée) plus 1

comme dans la sub toto je lui dis que RESULTAT = AJOUTE_UN(CHIFFRE) avec CHIFFRE= 2

La fonction prend NOMBRE = 2, prend elle même la valeur de NOMBRE +1 soit 2 + 1 et renvoie cette valeur, que j'affecte à RESULTAT dans Toto

Attention du coup à bien gérer les variables, si tu veux plus d'infos ou si tu as des questions (forcément vu l'explication rapide), n'hésite pas à rechercher sur le net ou demander ici ou carrément me MP, pour le moment ca ne sert à rien que je fasse un pavé sur cela dans ce sujet

En espérant ne pas trop te compliquer la tache ^^

ECG

Salut,

Merci beaucoup de ta réponse. Et ne t'en fait pas, c'est parfaitement ce qu'il me fallait.

Je testerais ça demain et je reviens vers toi pour d'indiquer ce que ça donne

Là c'est vraiment le cas de l'userform qui me posait problème, puisqu'on ne peut pas faire de :

call userform_commande (variable as string)

Mais les variables publiques devraient résoudre ce problème (je crains un léger soucis quand même, c'est que les variables publiques s'appliquent à un module non ? du coup comme l'userform est dans un module différent, le sien, ça risque de pas faire transiter l'info non ?)

En tout cas j'essaye et je te dis.

Merci encore.

Lorwin

Bonjour,

Je vois pas trop ce que tu cherches à faire mais pour savoir quelle case à cocher est cocher, une piste. A mettre dans le module du formulaire :

Sub CaseACocher()

    Dim Ctrl As Control

    For Each Ctrl In Me.Controls

        If TypeName(Ctrl) = "CheckBox" Then

            If Ctrl.Value = True Then MsgBox Ctrl.Name

        End If

    Next Ctrl

End Sub

Que tu peux appeler de la façon suivante :

Private Sub CommandButton1_Click()

    CaseACocher

End Sub

Il est possible d'avoir accès depuis l'extérieur du module du formulaire à une variable du formulaire mais pour ça, deux conditions, la variable doit être déclarée Public en tête du module et son appel doit être précédé du nom du module auquel elle appartient donc du formulaire. Un exemple :

Dans le module du formulaire, tu crées une variable en tête de module avec une portée publique :

Public MaVariable As String

Que tu initialises par exemple en cliquant sur le bouton :

Private Sub CommandButton1_Click()

    MaVariable = "Ceci est un test !"
    '...
    '...
    '...

End Sub

et dans un module standard, tu as le code suivant :

Sub TestVariable()

    MsgBox FenetreQuizz4.MaVariable

End Sub

Pour exécuter ce test, le formulaire doit avoir été lancé et que au préalable tu mettes sa propriété ShowModal à False (ici le formulaire "FenetreQuizz4") sinon, le compilateur reste fixé sur ce dernier et tu ne pourras pas exécuter un autre code. Une fois cliquer sur le bouton, tu retourne dans le VBE et dans le module "Module1" où se trouve la sub "TestVariable" et tu l'exécutes. Bien évidement, le formulaire doit resté ouvert durant le test

Super, merci beaucoup.

J'avais pas saisit l'appel du module avant la variable. C'est pour ça que ça marchait pas ^^ là c'est niquel.

J'ai un "nouveau" soucis par contre.

Comme tu peux le voir dans le fichier que je joins, quand je lance la macro, les variables "gouzi" et "houza" transitent bien, mais celle renseignée dans la macro contenant le unload retourne vide. Je les ais définis de la même façon, la seule chose qui change c'est qu'une est actualisé dans le _initialize et l'autre dans le _click.

Aurais tu une idée ?

Merci encore, l'import de données dans l'userform marche parfaitement avec le Public.

EDIT : Le ShowModal en False pose des problèmes chez moi. Quand je le fais, la macro initiale continu de tourner sans tenir compte des cases à cocher et du bouton cliqué.

20bug.xlsm (15.79 Ko)

J'ai résolu mon problème en copiant la valeur de ma variable dans une cellule et en la récupérant une fois de retour dans ma macro principale. C'est un peu une solution rustine mais qui fonctionne bien vu qu'il ne s'agit ici que d'un seule valeur à chaque Userform.

Mais ça m'intrigue que ça marche dans un sens et pas dans l'autre. Je reste toujours intéressé si vous avez une solution plus "propre" ^^

Re,

Pour que tu comprennes bien comment fonctionne VBA !

Quand tu écris un code et que tu l'exécutes, le compilateur lit le code comme toi, de haut en bas et de gauche à droite et pour lui dire de le faire, tu as plusieurs possibilités dont la première est F5 si tu es dans le VBE et le curseur dans la proc (F8 pour le pas à pas !), la seconde, un bouton ou tout autre objet auquel tu as attaché la macro ou proc la troisième, un événement (Initialize(), Click(), etc...) tant que la procédure n'a pas été appelée, le code quelle contient ne sera pas exécuté par le compilateur !

Comme tu peux le voir dans le fichier que je joins, quand je lance la macro, les variables "gouzi" et "houza" transitent bien, mais celle renseignée dans la macro contenant le unload retourne vide. Je les ais définis de la même façon, la seule chose qui change c'est qu'une est actualisé dans le _initialize et l'autre dans le _click.

C'est normal puisqu'elle n'a pas été initialisée !

Le Clic sur le bouton demande une action de ta part alors que Initialize() est exécuté quand tu demandes l'affichage de la Form !

Pour le test, remplace le code du module "Test" par celui-ci :

Sub UserForm() 'Essai "classique"

    gouzi = "question n°1"

    FenetreQuizz4.Show

    MsgBox "Variable houza : " & FenetreQuizz4.houza & vbCrLf & "Variable jacki : " & FenetreQuizz4.jacki

End Sub

et le code du module du formulaire par celui-ci :

Public houza As String
Public jacki As String

Private Sub userform_Initialize()

    With FenetreQuizz4

        .Label1.Caption = Test.gouzi

        houza = "coucou"

        .CheckBox1.Value = True
        .CheckBox3.Value = True

        CommandButton1_Click

    End With

End Sub

Private Sub CommandButton1_Click()

    'Récupération des données de l'UserForm (fenetre)

    Dim i As Integer

    jacki = ""

    With Me

        If .CheckBox1.Value = True Then 'je modifirais ça plus tard avec le Each
            jacki = jacki & "Case 1 - "
        End If

        If .CheckBox2.Value = True Then
            jacki = jacki & "Case 2 - "
        End If

        If .CheckBox3.Value = True Then
            jacki = jacki & "Case 3 - "
        End If

        If .CheckBox4.Value = True Then
            jacki = jacki & "Case 4 - "
        End If

    End With

    jacki = Left(jacki, Len(jacki) - 3)

    If jacki = "" Then jacki = "Aucune réponse cochée !"

End Sub

et lance la procédure "UserForm()" pour voir le résultat

Merci

Je pense avoir compris le fonctionnement.

Du coup dans l'exemple que tu as donné, les cases arrivent déjà cochées et renvoies instantanément le résultat à la subroutine principale qui continu. Et donc ne tient pas compte de ce que je coche moi même. C'est le problème que j'ai vu avec le Modal en False, ça ne tient pas compte de ce que je fais avec l'UserForm, ce qui réduit grandement son utilité.

Dans l'idée, je voulais

1- envoyer la liste des questions pour remplir l'userform automatiquement (ça c'est bon j'ai compris comment faire avec Public)

2- choisir les réponses aux questions en cochant les cases puis en validant (ça marche avec le FenetreQuizz4_click, en gros ça se met à jour à la fermeture de la fenêtre)

3- renvoyer la variable contenant la réponse dans la subroutine principale pour qu'elle la traite. (là ça marche pas mais la solution la plus simple a été de copier coller la valeur sur la feuille et de la récupérer par un =.cell(x,y).value puis clear.content de la cellule une fois fini

Merci beaucoup pour votre aide à tous les deux.

Lorwin

Rechercher des sujets similaires à "differents problemes userform"