简体   繁体   中英

How can I run a userform from a macro?

I developed many UDFs and macros in VBA for Excel 2016. One of my macros uses an Inputbox to get data used subsequently by the macro. I want to replace the Inputbox with a user form. I have created the user form, with one text box. I want to activate the user form, populating the text box with the default data, and return the text box data to the macro when OK is selected. I have searched extensively for an end-to-end example for all the the code needed to do this, with no luck. Does an example for this simple problem exist?

There is an example of how you can pass the value to a form and get the result back. The approach uses Scripting.Dictionary object created within standard module scope and passed to userform to allow values to be changed. So it makes possible to send the default values to userform, and keep the result values in the dictionary even after the userform is closed and unloaded. You may have multiple values, just add the necessary quantity of keys to the dictionary, eg oData("property1") , oData("property2") , etc.

Add a standard module to the project and put the below code into it:

Option Explicit

Sub Test()

    Dim oData

    ' Set default value and show form
    Set oData = CreateObject("Scripting.Dictionary")
    oData("") = "Some default text"
    UserForm1.ShowForm oData
    ' Wait until user close form
    Do While IsUserFormLoaded("UserForm1")
        DoEvents
    Loop
    ' Output returned value
    MsgBox oData("")

End Sub

Function IsUserFormLoaded(UserFormName As String) As Boolean

    Dim oUF As Object

    For Each oUF In UserForms
        If LCase(oUF.Name) = LCase(UserFormName) Then
            IsUserFormLoaded = True
            Exit Function
        End If
    Next

End Function

Add a userform module named UserForm1 to the project, place controls as shown:

用户表格

And put the below code into the userform module :

Private opData

Public Sub ShowForm(oData)

    Set opData = oData
    Me.TextBox1.Value = opData("")
    Me.Show

End Sub

Private Sub UserForm_Initialize()

    If TypeName(opData) <> "Dictionary" Then Set opData = CreateObject("Scripting.Dictionary")

End Sub

Private Sub CommandButton1_Click()

    Unload Me

End Sub

Private Sub CommandButton2_Click()

    opData("") = Me.TextBox1.Value
    Unload Me

End Sub

Add a Property to your user form. For this answer, let us use the following code within the user form.

Public Property Get MyResult() As String
    ' You may want to do any manipulation here
    ' including converting to a number, in which case the return type should be changed (*)
    MyResult = TextBox1.Text
End Property

(*) If you are doing conversion, you can have another function in your user form to disable the "OK" button until they have valid convertible data in the text box.

You also want to know if they have hit "Cancel"

Public Property Get Cancelled() As Boolean
    Cancelled = pCancelled ' Declare pCancelled as a Boolean in the scope of the form
End Property

Public Sub CancelButton_Click() ' Standard click event for the button
    pCancelled = True
    Me.Hide
End Sub

Public Sub OKButton_Click() ' Standard click event for the button
    pCancelled = False
    Me.Hide
End Sub

In your calling macro

MyForm.Show ' This is modal, so will block execution until a response is provided
If Not MyForm.Cancelled Then
    Debug.Print MyForm.MyResult
    'Do something with MyForm.MyResult
End If
UnLoad MyForm ' assuming you do not want to re-use this form as part of your logic.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM