Vba 从userform调用公共变量

Vba 从userform调用公共变量,vba,excel,Vba,Excel,在userform中,我在顶部有以下内容: Public DelMonth As Variant DelMonth的值是从一个组合框读取的,我可以从该userform中的不同子例程调用它。但是当我从一个单独的模块调用它时,它不会读取它。它甚至不会抛出错误。如果我做了一个MsgBox DelMonth,它什么也不做。表单是一个对象;对象模块中的公共字段属于该对象的实例。UserForms只不过是带有默认实例(即VB\u PredeclaredId=True属性)和设计器的类模块 如果您使用的是表

在userform中,我在顶部有以下内容:

Public DelMonth As Variant
DelMonth的值是从一个组合框读取的,我可以从该userform中的不同子例程调用它。但是当我从一个单独的模块调用它时,它不会读取它。它甚至不会抛出错误。如果我做了一个
MsgBox DelMonth
,它什么也不做。

表单是一个对象;对象模块中的公共字段属于该对象的实例。UserForms只不过是带有默认实例(即
VB\u PredeclaredId=True
属性)和设计器的类模块

如果您使用的是表单的默认实例(一个相当糟糕的主意),那么您可以执行以下操作:

MsgBox UserForm1.DelMonth
请注意,在全局对象中存储状态容易出现错误,最终会导致问题

如果您将表单视为一个成熟的类,那么您将得到如下结果:

With New UserForm1
    .Show
    MsgBox .DelMonth
End With
请注意,
Public
字段意味着任何人、任何地方都可以对其进行写入。您的意思是让表单确定其值,让调用方能够读取该值。您可以通过使用
属性Get
成员封装字段来实现这一点-首先将字段设置为Private:

Option Explicit
Private DelMonth As Variant ' wouldn't Integer or Long be more appropriate?

Public Property Get DeliveryMonth() As Long
    DeliveryMonth = DelMonth
End Property
现在,调用者不能看到私有的
DelMonth
,他们所能做的就是调用
get
访问器,这不会让他们篡改封装的值


它甚至不会抛出错误

这令人担忧。您允许VBA愉快地编译打字错误和其他非法代码。在每个模块的顶部指定
选项Explicit
。始终。

形式是对象;对象模块中的公共字段属于该对象的实例。UserForms只不过是带有默认实例(即
VB\u PredeclaredId=True
属性)和设计器的类模块

如果您使用的是表单的默认实例(一个相当糟糕的主意),那么您可以执行以下操作:

MsgBox UserForm1.DelMonth
请注意,在全局对象中存储状态容易出现错误,最终会导致问题

如果您将表单视为一个成熟的类,那么您将得到如下结果:

With New UserForm1
    .Show
    MsgBox .DelMonth
End With
请注意,
Public
字段意味着任何人、任何地方都可以对其进行写入。您的意思是让表单确定其值,让调用方能够读取该值。您可以通过使用
属性Get
成员封装字段来实现这一点-首先将字段设置为Private:

Option Explicit
Private DelMonth As Variant ' wouldn't Integer or Long be more appropriate?

Public Property Get DeliveryMonth() As Long
    DeliveryMonth = DelMonth
End Property
现在,调用者不能看到私有的
DelMonth
,他们所能做的就是调用
get
访问器,这不会让他们篡改封装的值


它甚至不会抛出错误


这令人担忧。您允许VBA愉快地编译打字错误和其他非法代码。在每个模块的顶部指定
选项Explicit
。始终。

您需要从窗体外部的任何例程使用
userformname.DelMonth
。您需要从窗体外部的任何例程使用
userformname.DelMonth
。我正在尝试在另存为对话框中从用户窗体调用DelMonth。这个对话框正在关闭userform。这就是为什么它不能抓取变量的原因吗?你是在向后做。表单的目的是收集/显示数据,而不是处理数据。表单不起任何作用。如果已卸载默认实例,则全局状态将被销毁,是的。请正确地处理事情,避免全局状态,并使用能够完成表单工作的表单。稍后谢谢你自己,我没听懂。我正在从userform ComboxBox设置DelMonth变量。在模块中,我需要在对话框中调用该变量。我是怎么倒过来的?好吧,抱歉我误解了。因此,模块在表单关闭后检索值,对吗?如果表单是
Unload
ed或X'd-out,则对象被销毁,状态丢失。您需要处理
QueryClose
事件以防止出现这种情况,并删除该表单中可能存在的任何
Unload Me
。请参阅文档中的。所以(趁着还没完成,赶快看!遮阳文档也是如此)从技术上来说,是的。我将SaveAs框设置为在卸载之前打开,但该对话框似乎强制用户窗体自动关闭。我试图在SaveAs对话框中从用户窗体调用DelMonth。这个对话框正在关闭userform。这就是为什么它不能抓取变量的原因吗?你是在向后做。表单的目的是收集/显示数据,而不是处理数据。表单不起任何作用。如果已卸载默认实例,则全局状态将被销毁,是的。请正确地处理事情,避免全局状态,并使用能够完成表单工作的表单。稍后谢谢你自己,我没听懂。我正在从userform ComboxBox设置DelMonth变量。在模块中,我需要在对话框中调用该变量。我是怎么倒过来的?好吧,抱歉我误解了。因此,模块在表单关闭后检索值,对吗?如果表单是
Unload
ed或X'd-out,则对象被销毁,状态丢失。您需要处理
QueryClose
事件以防止出现这种情况,并删除该表单中可能存在的任何
Unload Me
。请参阅文档中的。所以(趁着还没完成,赶快看!遮阳文档也是如此)从技术上来说,是的。我将SaveAs框设置为在
Unload
ed之前打开,但该对话框似乎强制用户表单自动关闭。