将公共方法添加到 VBA 中的用户表单模块

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20922511/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-12 01:12:32  来源:igfitidea点击:

Add Public Methods to a Userform Module in VBA

excelvbaexcel-vba

提问by Cool Blue

Is it possible to call a public sub located in a UserFormfrom a Class Module? 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 UserFormsin VBA? It is exposed inside the UserFormCode Module, I can see it in the intelisense for the Meobject, but I can't seem to access it from outside the Form Module.

是否可以UserForm从 a调用位于 a 中的公共子Class Module?我想在表单模块中放置一个回调,但我似乎无法让它公开。
这是UserFormsVBA 中的基本限制吗?它在UserForm代码模块内部公开,我可以在Me对象的智能感知中看到它,但我似乎无法从表单模块外部访问它。

回答by Dick Kusleika

The only difference between a Userform and Class Module is that a Userform has a UI element that a Class Module doesn't. So a Userform is just a special type of Class Module. That means that Public Subs inside a Userform behave just as they do in any other class - as a method of the class.

用户窗体和类模块之间的唯一区别是用户窗体具有类模块没有的 UI 元素。所以用户表单只是一种特殊类型的类模块。这意味着 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.

要访问类模块(例如用户表单)中的 Public Sub,您需要实例化该类,然后调用该方法。

Dim uf1 As UserForm1

Set uf1 = New UserForm1
Uf1.MyPublicSub

回答by Cool Blue

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.

我的问题的真正答案是更好地理解 UserForms,因为我找不到很好的参考资料,所以我想我会回答我自己的问题来分享我的学习。

Thanks to @Dick Kusleika for the key insight!

感谢@Dick Kusleika 的重要见解!

First of all, this is not a UserForm:

首先,这不是一个UserForm

enter image description here

在此处输入图片说明

It is no more a Form than a Class Moduleis a variable. UserForm1is a Class Modulewith a GUI and with the following default, inherited properties enter image description here

它不再是一个表单,就像 aClass Module是一个变量。 UserForm1Class Module具有 GUI 和以下默认继承属性的 在此处输入图片说明

These properties are like a standard Interfacethat is common to all Form Class Modulesand therefore instances. The Name property is in parentheses because it is not the name of the object, it is the name of the the Typethat is used to declare variables to instantiate the particular Form Class.

这些属性就像Interface是所有 FormClass Modules和实例通用的标准。Name 属性在括号中,因为它不是对象的名称Type,而是用于声明变量以实例化特定 Form Class 的名称。

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.

在此示例中,表单类名称用作默认实例名称。

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.Showand this is very confusing and misleading. To me it implies that you are showing the Objectcalled UserForm1but you are not. 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 Typeonly worse, because there is no referencing variable.

您可以使用创建表单的实例,UserForm1.Show这是非常令人困惑和误导的。对我来说,这意味着您正在显示被Object调用者,UserForm1但您没有显示。我不知道您为什么要使用此方法,因为除了令人困惑之外,它不会提供对创建的对象的任何直接引用。它有点像Dim v as New Type更糟,因为没有引用变量。

You can instantiate a Form Class in exactly the same way you can a Custom Class object and thenuse the show method to deploy it...

您可以以与自定义类对象完全相同的方式实例化表单类,然后使用 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. I just treat them as Class Modules and its fine.

对我来说,在理解了上述内容之后,我对 UserForms 的所有困惑和我对找不到合适参考的沮丧都消失了。我只是将它们视为类模块,这很好。