2017-07-04 2 views
1

J'ai créé un UserForm VBA qui est essentiellement une zone de saisie glorifiéTraiter Userform comme une fonction

Tout comme une boîte d'entrée peut être utilisé comme celui-ci

Dim returnVal As String 
returnVal = InputBox("Write some string") 

Je voudrais que mon userform à courir comme ce

Dim returnVal As customClass 
Set returnVal = MyUserForm([some arguments]) 

ie. le code MyUserForm() transmet certains arguments au userform, et lorsque le userform est fermé, il récupère des arguments (sous la forme d'une classe personnalisée plutôt que d'une chaîne normale)

Quelle est la meilleure façon de structurer mon userform autoriser cette fonctionnalité?


Actuellement, je suis juste de déclarer certaines variables et la classe personnalisée publiquement. J'attrape les clics du bouton de commande et les événements Query_close() pour masquer le formulaire, puis je lis le outputVal et ferme complètement le formulaire. Je n'aime pas ça parce que j'aimerais que mon formulaire soit totalement autonome, et je pense que la capture d'événements est désordonnée.

Dans le code simplifié (lecture/retourner une chaîne):

Function myUf(inVal As String) As String 
Dim frm As New frmTest 
frm.inputval = inVal 
frm.Init 'sets caption. We cannot rely on userform initialize as this runs before inputval is set 
     'We could pass a variable here to save writing to the public variable 
frm.Show 
myUf = frm.outputVal 
Set frm = Nothing 
End Function 

Et dans mon Userform appelé frmTest avec une zone de texte appelé tb1

Public inputval As String 
Public outputVal As String 

Public Sub Init() 
Me.Caption = inputval 'setting caption, but could pass this anywhere 
End Sub 

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) 
If CloseMode <> 1 Then Cancel = 1 
outputVal = tb1 'reading value from textbox, but could return anything here 
Me.Hide 
End Sub 

Répondre

0

L'idée de base est la suivante:

Créer une fonction dans laquelle vous combinez vos arguments à une chaîne comme:

strOpenArg = "param1:=value1;param2:=value2;" 

que d'ouvrir le formulaire avec les OpenArgs

DoCmd.OpenForm "UserForm", acNormal, , , , acDialog, strOpenArgs 

obtenir votre valeur et fermez le formulaire

Value= Form_UserForm.Value 

DoCmd.Close acForm, "UserForm", acSaveNo 

dans le UserForm mis Form_Open. Ici vous pouvez obtenir vos paramètres. Vous pouvez diviser cela en séparant les chaînes. Définissez également un bouton OK, où vous faites la forme juste invisible et définissez la valeur de retour

Private Sub Form_Open(Cancel As Integer) 
    Dim strParameter as String 
    strParameter = Me.OpenArgs 'Here are your parmeters 
End Sub 

Private Sub ok_Click() 
    m_Value = "Your ReturnValue" 
    Me.Visible = False 
End Sub 

Private m_Value As String 
Public Property Get Value() As String 
    Value = m_msgBoxResult 
End Property 
+1

Il s'agit du code pour un formulaire MSAccess, pas de code pour un Userform VBA. – jkpieterse

0

Il n'y a pas moyen de le code uniligne comme vous voulez, malheureusement. Si tout le code de votre userform est autonome, la seule façon de transmettre les valeurs est de changer les valeurs des variables publiques. Mat's Mug's answer here est la disposition que j'utilise habituellement lorsque j'essaie de simuler des fonctions comme 'InputBox' mais vous ne pouvez toujours pas l'obtenir en une ligne sans écrire une fonction séparée. L'utilisation des propriétés de formulaire utilisateur vous permet de contenir plus de votre code dans le formulaire lui-même.

2

Vous devez trouver un moyen d'initialiser l'objet UserForm à partir d'un ClassObject. Ensuite, vous pouvez utiliser un simple factory pattern pour créer l'UserForm exactement comme vous le souhaitez.


En général, j'ai copié un peu du code de Mat's Mug quelque part dans StackOverflow et moi avons écrit un article sur les formulaires utilisateur. Si vous jetez un oeil ici (http://www.vitoshacademy.com/vba-the-perfect-userform-in-vba/) vous trouverez un moyen d'initialiser le formulaire avec Public Sub ShowMainForm() Il est possible d'ajouter un paramètre à la ShowMainForm, puis de le passer à l'initialisateur de la classe.

En général, prendre le code de l'article, assurez-vous qu'il fonctionne, et changer le ShowMainForm initialiseur à ce qui suit:

Public Sub ShowMainForm(strText As String, strText2 As String) 

    If (objPresenter Is Nothing) Then 
     Set objPresenter = New clsSummaryPresenter 
    End If 

    objPresenter.Show 
    Call objPresenter.ChangeLabelAndCaption(strText, strText2) 

End Sub 

Ensuite, si vous appelez comme ça dans la fenêtre immédiate:

call ShowMainForm("Just","testing") 

Vous obtiendrez ceci:

enter image description here

Ce qui est tout à fait ce dont vous avez besoin. :)

+0

apprécié votre article +. Il pourrait être intéressant de jeter un coup d'œil à ma question récemment publiée sur la façon de «détruire correctement une instance * modeless * userform», comme je l'ai également mentionné dans le concept MVP de Mat's Mug (voir https://stackoverflow.com/questions/ 47357708/vba-destroy-a-modeless-userform-instance-correctement). –