Vous trouverez ci-dessous une question à laquelle je répondrai moi-même. Toutefois, cela m'a causé beaucoup de frustration et j'ai eu beaucoup de difficulté à la rechercher sur le Web. Je poste ici dans l'espoir de gagner du temps et de faire des efforts pour les autres, et peut-être pour moi si j'oublie cela à l'avenir:
Pour VBA (dans mon cas, MS Excel), la déclarationPublic
EST SUPPOSÉE RENDRE LA VARIABLE (OU LA FONCTION) GLOBALEMENT ACCESSIBLE PAR D’AUTRES FONCTIONS OU SOUS-ROUTINES DE CE MODULE, AINSI QUE DE TOUT AUTRE MODULE.
IL S'AVÈRE QUE CE N'EST PAS VRAI DANS LE CAS DE Forms
, et je soupçonne également dans Sheets
, mais je n'ai pas vérifié le dernier.
En bref, les suivants NE créeront PAS de variable publique/accessible lorsqu’ils sont créés dans un Form
, et planteront donc, indiquant que les variables bYesNo et dRate ne sont pas définies dans mModule1:
(inside fMyForm)
Public bYesNo As Boolean`
Public dRate As Double
Private Sub SetVals()
bYesNo = Me.cbShouldIHaveADrink.value
dRate = CDec(Me.tbHowManyPerHour.value)
End Sub
(Presume the textbox & checkbox are defined in the form)
(inside mModule1)
Private Sub PrintVals()
Debug.Print CStr(bYesNo)
Debug.Print CStr(dRate)
End Sub
Cependant, si vous faites la légère modification ci-dessous, tout fonctionnera correctement:
(inside fMyForm)
Private Sub SetVals()
bYesNo = Me.cbShouldIHaveADrink.value
dRate = CDec(Me.tbHowManyPerHour.value)
End Sub
(Presume the textbox & checkbox are defined in the form)
(inside mModule1)
Public bYesNo As Boolean`
Public dRate As Double
Private Sub PrintVals()
Debug.Print CStr(bYesNo)
Debug.Print CStr(dRate)
End Sub
mModule1
fonctionnera parfaitement et, en supposant que le fMyForm soit toujours appelé en premier, puis, au moment où la routine PrintVals
est exécutée, les valeurs de la zone de texte et de la case à cocher du formulaire seront correctement capturées.
Honnêtement, je ne peux vraiment pas comprendre ce que MS pensait de ce changement, mais le manque d'uniformité nuit à l'efficacité, car il permet d'apprendre des idiosyncracies comme celles-ci, qui sont si peu documentées qu'une recherche Google en 2013 est probablement si difficile à chercher.
Premier commentaire:
Les modules Userform et Sheet sont des modules Object: ils ne se comportent pas de la même manière qu'un module standard. Vous pouvez toutefois faire référence à une variable dans un formulaire utilisateur de la même manière que vous feriez référence à une propriété de classe. Dans votre exemple, faire référence à fMyForm.bYesNo fonctionnerait correctement. Si vous n'aviez pas déclaré bYesNo en tant que public, le code ne serait pas visible en dehors du formulaire. Ainsi, lorsque vous le rendez public, il est vraiment différent de non public. - Tim Williams 11 avr. 13 à 21:39
est en fait une réponse correcte ...
En guise de réponse rapide à la réponse de la communauté, juste pour vous prévenir:
Lorsque vous instanciez vos formulaires, vous pouvez utiliser l'objet de formulaire lui-même ou vous pouvez créer une nouvelle instance de l'objet de formulaire en utilisant Nouveau et en le plaçant dans une variable. La dernière méthode est la méthode IMO la plus propre, car elle rend l’utilisation moins singleton-ish.
Toutefois, lorsque vous appelez Décharger (Me) dans votre formulaire utilisateur, les membres all public seront effacés. Donc, si votre code va comme ceci:
Dim oForm as frmWhatever
Set oForm = New frmWhatever
Call oForm.Show(vbModal)
If Not oForm.bCancelled Then ' <- poof - bCancelled is wiped clean at this point
La solution que j’utilise pour éviter cela, et c’est une solution alternative intéressante pour le PO également, consiste à capturer tous les IO avec le formulaire (c’est-à-dire tous les membres publics) dans une classe séparée et à utiliser une instance. de cette classe pour communiquer avec le formulaire. Donc, par exemple.
Dim oFormResult As CWhateverResult
Set oFormResult = New CWhateverResult
Dim oForm as frmWhatever
Set oForm = New frmWhatever
Call oForm.Initialize(oFormResult)
Call oForm.Show(vbModal)
If Not oFormResult.bCancelled Then ' <- safe