简体   繁体   English

将公共方法添加到VBA中的Userform模块

[英]Add Public Methods to a Userform Module in VBA

Is it possible to call a public sub located in a UserForm from a Class Module ? 是否可以从Class Module调用位于UserForm的公共子? I want to put a callback in the Form Module but I can't seem to get it to expose. 我想在表单模块中添加一个回调,但我似乎无法公开它。
Is this a fundamental limitation of UserForms in VBA? 这是VBA中UserForms的基本限制吗? It is exposed inside the UserForm Code Module, I can see it in the intelisense for the Me object, but I can't seem to access it from outside the Form Module. 它里面暴露UserForm代码模块,我可以看到它在智能感知为Me对象,但我似乎无法从窗体模块外访问它。

The only difference between a Userform and Class Module is that a Userform has a UI element that a Class Module doesn't. Userform和Class Module之间的唯一区别是Userform具有类模块没有的UI元素。 So a Userform is just a special type of Class Module. 因此,Userform只是一种特殊类型的类模块。 That means that Public Subs inside a Userform behave just as they do in any other class - as a method of the class. 这意味着Userform中的Public Subs就像在任何其他类中一样 - 作为类的方法。

To access a Public Sub inside a class module (such as a userform), you need to instantiate the class, then call the method. 要访问类模块(例如userform)中的Public Sub,您需要实例化该类,然后调用该方法。

Dim uf1 As UserForm1

Set uf1 = New UserForm1
Uf1.MyPublicSub

The real answer to my question is to have a better understanding of UserForms and since I could not find a good reference for that I thought I would answer my own question to share my learnings. 我的问题的真正答案是更好地理解用户形式,因为我找不到一个很好的参考,我想我会回答我自己的问题来分享我的学习。

Thanks to @Dick Kusleika for the key insight! 感谢@Dick Kusleika的关键见解!

First of all, this is not a UserForm : 首先,这不是UserForm

在此输入图像描述

It is no more a Form than a Class Module is a variable. 它不再是一个Form而不是一个Class Module是一个变量。 UserForm1 is a Class Module with a GUI and with the following default, inherited properties UserForm1是一个具有GUI的Class Module ,具有以下默认的继承属性 在此输入图像描述

These properties are like a standard Interface that is common to all Form Class Modules and therefore instances. 这些属性类似于所有表单Class Modules和实例所共有的标准Interface The Name property is in parentheses because it is not the name of the object, it is the name of the the Type that is used to declare variables to instantiate the particular Form Class. Name属性在括号中,因为它不是对象的名称,它是用于声明变量以实例化特定Form类的Type的名称。

More properties and methods can be added by the user at design time and this is done in exactly the same way as a Class Module. 用户可以在设计时添加更多属性和方法,这与类模块完全相同。

For example, in a Form Module... 例如,在表单模块中...

Option Explicit
Dim mName As String
Property Let instName(n As String)
    mName = n
End Property
Property Get instName() As String
    If Len(mName) = 0 Then mName = Me.Name
    instName = mName
End Property

In this example, the Form Class Name is used as the default Instance Name. 在此示例中,Form Class Name用作默认的Instance Name。

When you add Controls to the form, its like graphically adding 当您向表单添加控件时,它就像图形添加一样

Public WithEvents controlName As MSForms.ControlType

...in a Class Module. ......在课堂模块中。

The Methods inherited in the standard interface include one called Show. 标准接口中继承的方法包括一个名为Show的方法。

You can create an instance of a form using UserForm1.Show and this is very confusing and misleading. 您可以使用UserForm1.Show创建表单的实例,这非常令人困惑和误导。 To me it implies that you are showing the Object called UserForm1 but you are not. 对我而言,这意味着您正在显示名为UserForm1Object但您不是。 I don't know why you would want to use this method because, apart from being confusing, it does not deliver any direct reference to the object created. 我不知道你为什么要使用这种方法,因为除了令人困惑之外,它不会直接引用所创建的对象。 Its a bit like Dim v as New Type only worse, because there is no referencing variable. 它有点像Dim v as New Type只会更糟,因为没有引用变量。

You can instantiate a Form Class in exactly the same way you can a Custom Class object and then use the show method to deploy it... 您可以用与Custom Class对象完全相同的方式实例化Form Class, 然后使用show方法来部署它...

Dim f As UserForm1
    Set f = New UserForm1
    f.Show

For me, this is the preferred method. 对我来说,这是首选的方法。 You can add custom properties and controls to the UserForm1 Class and you can give it a meaningful name when creating it, but you can also reference it using the standard UserForm interface. 您可以向UserForm1类添加自定义属性和控件,您可以在创建它时为其指定一个有意义的名称,但您也可以使用标准的UserForm接口来引用它。

For example 例如

'In a Class Module
Dim mForm as UserForm1
Property let Form(f as MSForms.UserForm)
    Set mForm = f
End Property

For me, after understanding the above, all of my confusion about UserForms and my frustration at not being able to find a decent reference disappears. 对我来说,在理解了上述内容后,我对UserForms的所有混淆以及我对无法找到合适引用的挫败感都消失了。 I just treat them as Class Modules and its fine. 我只是将它们视为类模块而且很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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