VBA excel 引用用户窗体作为获取数据的变量

VBA excel Reference Userform as variable to get data

我有几天时间来解决这个问题。我正在使用 excel VBA 填写 Word 文档。 我有多个包含文本框、组合框等的用户表单,为了保持代码小而不是一遍又一遍地创建相同的模块,我只需要更改 FormName

此代码用于填写 Word 文档

wDoc.SelectContentControlsByTitle("#MonthBox").Item(1).Range.Text = Request_Form_1.MonthBox.Value

但我想使用变量来引用模块中的用户窗体,但我遇到了所有类型的错误

Dim FormName As String
FormName = "Request_Form_1"
wDoc.SelectContentControlsByTitle("#MonthBox").Item(1).Range.Text = FormName.MonthBox.Value

亲切的问候

感谢您的支持 我尝试过但没有用的东西

  1. 尝试过用户表单(NumeForma) MsgBox UserForms(NumeForma).LunaBox.Value 表格可见,但我得到 错误 13 类型不匹配
  2. 试图插入包含 ShowAnyForm() 调用的模块 MsgBox ShowAnyForm(NumeForma).LunaBox.Value 错误“预期函数或变量”
  3. 使用 MsgBox ShowAnyForm(NumeForma).LunaBox.Value 需要错误 424 对象
  4. 将模块 ShowAnyForm()Sub 更改为 Function

点之前或之后的所有内容(例如 FormName.)都不能(简单)替换为变量,因为它是对象或成员(但您可以 CallByName! ).

变量必须作为参数传递给参数,但是由于集合可以访问许多对象,所以我们通常采用这种方式。

Loaded 用户表单可以在 UserForms 集合中找到。但是它们只能通过它们的项目索引(0 到 UserForms.Count() -1)访问,而不是它们的名称。所以你需要……喜欢:

'code by http://www.cpearson.com/Excel/showanyform.htm
For Each Obj In VBA.UserForms
     If StrComp(FormName, Obj.Name, vbTextCompare) = 0 Then ' If Obj.Name matches FormName loop is exited and Obj contains the UserForm reference of FormName.
         Exit For
     End If
Next Obj

获取加载的用户窗体参考。 示例代码可在 Show Any Form.

获得

您的代码应如下所示:

wDoc.SelectContentControlsByTitle("#MonthBox").Item(1).Range.Text = ControlValueByName(FormName:=FormName, ControlName:="MonthBox", _
        ProcName:="Value", CallType:=vbGet)

我将函数添加到 return 给定 FormName 的用户窗体引用:

'Code inspired by http://www.cpearson.com/Excel/showanyform.htm
Public Function UserFormByName(ByVal FormName As String) As UserForm
Dim Obj As Variant
For Each Obj In VBA.UserForms
    If StrComp(FormName, Obj.Name, vbTextCompare) = 0 Then
        Exit For
    End If
Next Obj
If Obj Is Nothing Then ' UserForm not loaded
    Err.Clear
    Set Obj = VBA.UserForms.Add(FormName)
    If Err.Number <> 0 Then
        MsgBox "Error Calling Form: " & FormName
        Exit Function
    End If
End If
Set UserFormByName = Obj
End Function

现在您可以使用:

wDoc.SelectContentControlsByTitle("#MonthBox").Item(1).Range.Text = UserFormByName(FormName).MonthBox.Value

如果您从用户窗体调用方法,事情会变得更容易,因为您可以简单地将引用传递给它。参见 OP

表格中:

Private Sub InregistreazaButtonActive2_Click()
    ToWord Me
End Sub

在模块中:

Sub ToWord(ByRef Caller As UserForm)
    MsgBox Caller.AnBox.Value
End Sub

您可以传递包含表单引用的列表框引用,而不是表单引用,因为它是表单的子对象,所以表单是 ListBox.Parent.

Private Sub InregistreazaButtonActive2_Click()
    ToWord Me.AnBox
End Sub

Sub ToWord(ByRef CallerListBox As ListBox)
    MsgBox CallerListBox.Value
    Debug.Print CallerListBox.Parent.Name ' shows form name of listbox 
End Sub

通过传递引用,您不必担心多个实例(会有相同的名称),因为每个实例都有自己的引用。

首先我想说谢谢@ComputerVersteher 二会贴孔码

  1. 在 excel 工作表中我有一个形状,单击将调用该表格
Sub Start_Cerere_De_Autentificare_1_Click()
    Cerere_De_Autentificare_2.Show False
End Sub
  1. 在表单上我有 3 个文本框(ZiBox、LunaBox、AnBox)
Public Sub UserForm_Activate()
     ZiBox = Day(Date)
     LunaBox = Month(Date)
     AnBox = Year(Date)
End Sub
Private Sub InregistreazaButtonActive2_Click()
    Call ToWord_CerereDeAutentificare2
End Sub
  1. 按下注册按钮时会调用
Sub ToWord_CerereDeAutentificare2()

    Dim NumeForma As String
    NumeForma = "Cerere_De_Autentificare_2"

    Dim AllName As Object
    Set AllName = UserFormByName(NumeForma)

    MsgBox AllName.AnBox.Value
End Sub
  1. 这将调用您的代码,该代码将 return 表单名称,最后存储在文本框中的值可以通过一行轻松访问 MsgBox AllName.AnBox.Value
Public Function UserFormByName(FormName As String) As UserForm
Dim Obj As Variant
For Each Obj In VBA.UserForms
    If StrComp(FormName, Obj.Name, vbTextCompare) = 0 Then
        Exit For
    End If
Next Obj
If Obj Is Nothing Then ' UserForm not loaded
    Err.Clear
    Set Obj = VBA.UserForms.Add(FormName)
    If Err.Number <> 0 Then
        MsgBox "Error Calling Form: " & FormName
        Exit Function
    End If
End If
Set UserFormByName = Obj
End Function

再次感谢您