VBA:如何将表单作为参数传递

时间:2014-03-10 14:14:09

标签: excel vba userform

我有一个简单的用户表单,上面有一个按钮。我想将此表单传递给另一个模块中的函数 - 但即使在同一个模块中,它也无法按预期工作:

Private Sub Test(ByRef oForm As MSForms.UserForm)
    Debug.Print "caption: >" & oForm.Caption & "<"
End Sub

Private Sub CommandButton3_Click()
    Debug.Print "caption: >" & Me.Caption & "<"
    Test Me
    Debug.Print "caption: >" & Me.Caption & "<"
End Sub

当我单击按钮时,它会将其打印到调试控制台:

caption: >UserForm1<
caption: ><
caption: >UserForm1<

所以在Test()子内部,Caption为空。

为什么这不起作用的任何想法?

注意:如果我使用Variant作为参数类型,则可以使用

6 个答案:

答案 0 :(得分:4)

类型UserForm并不等同于特定用户表单的实例,并且呈现的界面略有不同。

传递表格as Object

Private Sub Test(Form As Object)

或者对于类型安全的方法,UserForm可以实现接口:

Private Sub Test(Form As IMyForm)

答案 1 :(得分:0)

您必须传递UserForm类型的变量。这意味着如果您的表单名称为MyForm,则签名应为

Private Sub Test(ByRef oForm As MyForm)

答案 2 :(得分:0)

对我有用的是以下......

1)在主模块中定义全局参数,如下所示:

Public gMyForm As MSForms.UserForm

2)在UserForm_Initialize()子目录中:

Set gMyForm = Me

3)调用函数:

Dim l_dummy as Variant
l_dummy = myFunction(gMyForm)

4)函数签名加上几行随机代码:

Function myFunction(ByRef p_form As MSForms.UserForm) 

Dim l_my_value type string
l_my_value = p_form.myControl.Value  

唯一的怪异,无疑有人可以解释,是需要指定l_dummy返回参数,否则你会得到类型不匹配错误。工作就像一个魅力,否则..

希望这有助于某人。

答案 3 :(得分:0)

“毫无疑问,唯一可以解释的怪异之处是 指定l_dummy返回参数,否则您将得到类型不匹配的信息 错误。否则就像魅力一样。希望这对某人有帮助。”

这些是语言语法的功能。 您使用该函数,但不指定返回值的类型。 如果您不需要返回任何内容,请使用Sub()。 如果函数返回内容,则必须指定方括号:

variant ret = myFunction(gMyForm)

如果没有返回:

myFunction gMyForm

为避免创建不必要的变量: 不返回:myFunction Me 返回:... = myFunction(Me) 签名方法/功能:

Sub myFunction(p_form As MyForm)
........
End Sub

Function myFunction(p_form As MyForm) As Variant
............
   myFunction = p_form.myControl.Value
End Function

答案 4 :(得分:0)

以下是我找到的解决方案。重要的部分是:

  1. 在进入 Sub 的 Call 站点,如果参数在括号内,则需要 Call 。当我省略 Call 并保留参数周围的括号时,我收到错误 Run-time error '438': Object doesn't support this property or method。在错误对话框中选择“调试”时,我进入了 VBA 编辑器,它表明 .Visible 本身中的 Sub 引用是未找到的。删除参数周围的括号后,错误就会消失。
  2. Sub 中,接受表单 pv_objFrmTarget 的参数必须定义为 ByVal。它不能明确定义为 ByRef 或未定义(默认为 ByRef)。当我使用 ByRef 或省略它时,我收到了 Run-time error '13': Type Mismatch 的错误。在错误对话框中选择“调试”时,我进入 VBA 编辑器,它表明 Call s_... 语句出错(因为它正在尝试在完成后更新 ByRef 值电话)。
  3. Sub 中,接受表单 pv_objFrmTarget 的参数类型必须定义为 As ObjectAs Variant 或根本不定义(我相信会导致默认为 As Variant)。将其定义为“UserForm”会导致错误 Run-time error '438': Object doesn't support this property or method。在错误对话框中选择“调试”时,我进入了 VBA 编辑器,它表明 .Visible 本身中的 Sub 引用是未找到的内容。

解决方案 1:

呼叫站点的代码:

Sub btnClear_Click()
  Call s_FrmShowCenteredOnlyIfHidden(frmClear)
End Sub

Sub 站点上的代码:

Public Sub s_FrmShowCenteredOnlyIfHidden(ByVal pv_objFrmTarget As Object)
  With pv_objFrmTarget
    If (.Visible = False) Then
      .StartUpPosition = 0
      .Left = Application.Left + (0.5 * Application.Width) - (0.5 * .Width)
      .Top = Application.Top + (0.5 * Application.Height) - (0.5 * .Height)
      .Show
    End If
  End With
End Sub

解决方案 2:[所有默认值]

呼叫站点的代码:

Sub btnClear_Click()
  s_FrmShowCenteredOnlyIfHidden frmClear
End Sub

Sub 站点上的代码:

Public Sub s_FrmShowCenteredOnlyIfHidden(ByVal pv_objFrmTarget)
  With pv_objFrmTarget
    If (.Visible = False) Then
      .StartUpPosition = 0
      .Left = Application.Left + (0.5 * Application.Width) - (0.5 * .Width)
      .Top = Application.Top + (0.5 * Application.Height) - (0.5 * .Height)
      .Show
    End If
  End With
End Sub

答案 5 :(得分:-1)

将用户表单作为 Object 传递,如下所示:

..
Call Subroutine(Me)
..

Sub Subroutine(Dialog As Object)
    Dim UF As Object
    Set UF = Dialog
    Debug.Print Dialog.caption, UF.caption
End Sub