[英]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. 我在VBA中为Excel 2016开发了许多UDF和宏。我的一个宏使用Inputbox来获取宏随后使用的数据。 I want to replace the Inputbox with a user form.
我想用用户表单替换Inputbox。 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. 该方法使用在标准模块范围内创建并传递给用户窗体的
Scripting.Dictionary
对象,以允许更改值。 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. 您可能有多个值,只需将必要数量的键添加到字典中,例如
oData("property1")
, oData("property2")
等。
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: 将名为
UserForm1
模块添加到项目中,放置控件,如下所示:
And put the below code into the userform module : 并将以下代码放入userform模块:
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.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.