【问题标题】:VBA how to pass userform variables to subroutineVBA如何将用户表单变量传递给子程序
【发布时间】:2018-11-21 12:44:41
【问题描述】:

我正在尝试使用子程序从用户表单输入中调用变量。 但是,即使我可以通过将其打印到工作表来在用户表单中正确显示用户表单输入,但我似乎无法将其作为公共变量传递给子例程。当我调用子程序中的变量时,它们都是空的。

我以此为指导: Passing variable from Form to Module in VBA

这是我的代码:

Public a As String
Public b As Double
Public c As String

Private Sub OKButton_Click()
'from userform
    a = TextBox1.Value
    b = TextBox2.Value
    c = TextBox3.Value

    Cells(1, 1).Value = a
    Cells(2, 1).Value = b
    Cells(3, 1).Value = c
    'this displays the inputs properly
    Unload UserForm1
End Sub

在模块中:

Public Sub Login()
'in module
    UserForm1.Show
    MsgBox (a)
    MsgBox (b)
    MsgBox (c)

End Sub

【问题讨论】:

  • 文本框的值始终是字符串

标签: excel vba


【解决方案1】:

这样做。将您的公共变量放入模块代码中。

Public a As String
Public b As Double
Public c As String

Public Sub Login()
'in module
    UserForm1.Show
    MsgBox (a)
    MsgBox (b)
    MsgBox (c)

End Sub

【讨论】:

  • 嗯,无论是在模块或用户窗体中声明公共变量还是在两者中声明,我都会遇到同样的问题
  • @abcdefg12345,公共变量必须只在模块中声明,才能正常工作。
  • 谢谢。我很困惑,因为我在调用公共变量的行顶部有几个 subs,但后来我把调用公共变量的行放在模块的最顶部,它最终工作了。
【解决方案2】:

我正在开发一个用户应用程序,与您现在面临的问题相同,here is the answer I got there.

请检查上面的链接,因为 Mat's Mugs 的解释超出了我解释该主题的能力。但这里有一个缩写。

基本上你做的是以下。您有三个类:模型、视图和演示者类。这听起来超级复杂,但一旦你掌握了它,它就真的没那么难了。

模型

是一个存储所有数据的类模块。因此,您不必声明一堆公共变量,而是拥有一个存储所有数据的大类。您还可以将多个模型类和类作为类成员,但为简单起见,我们仅采用上述三个整数。

这里是一个model 类的例子:(把它全部放在一个名为model 的类模块中)

   Option Explicit

    ' encapsulated data
    Private Type TModel
        a As Integer
        b As Integer
        c As Integer
    End Type

    Private this As TModel

    ' property get and property let define the way you can interact with data
    Public Property Get a() As String
         a = this.a
    End Property
    Public Property Let a(ByVal value As String)
         this.a = value
    End Property

    Public Property Get b() As String
         b = this.b
    End Property
    Public Property Let b(ByVal value As String)
         this.b = value
    End Property

    Public Property Get c() As String
         c = this.c
    End Property
    Public Property Let c(ByVal value As String)
         this.c = value
    End Property

观点

这是您的用户表单。但是您的 UserForm 又是一个类,所以除了所有其他代码之外,您还有以下代码:

Private Type TView
    M As Model
    IsCancelled As Boolean
    IsBack As Boolean
End Type

Private this As TView

Public Property Get Model() As Model
    Set Model = this.M
End Property

Public Property Set Model(ByVal value As UImodel)
    Set this.M= value
    'Validate
End Property

' This is responsible for not destroying all data you have when you x-out the userform
Public Property Get IsCancelled() As Boolean
    IsCancelled = this.IsCancelled
End Property

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = VbQueryClose.vbFormControlMenu Then
        this.IsCancelled=True
        Cancel = True
        OnCancel
    End If
End Sub

Private Sub OKButton_Click()
    Model.a = TextBox1.value
    Model.b = TextBox2.value
    Model.c = TextBox3.value

    Cells(1, 1).value = Model.a
    Cells(2, 1).value = Model.b
    Cells(3, 1).value = Model.c
    'this displays the inputs properly
    Me.Hide
End Sub

演示者

这是一个普通的模块。您简单地将代码放在您使用这些东西的地方。因此,对于您的示例代码,如下所示:

Public Sub Login()
'in module
Dim Ufrm As New UserForm1
Dim M As New Model

    Set Ufrm.Model = M
    Ufrm.Show
    If Ufrm.IsCancelled Then Exit Sub
    Set M = Ufrm.Model

    MsgBox M.a
    MsgBox M.b
    MsgBox M.c
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多