宏中的用户窗体控制变量
Userform controlled variables within a macro
早安,
我的项目 运行 遇到了一个小障碍。我是 VBA 的新手,正在尽最大努力 'learn by doing' 但我似乎无法理解 macro/userform 互动。
我有一个包含一个文本框和 9 个复选框的用户表单。这应该显示用户表单,允许用户指定 sheet 名称,以及(来自 9 个用户的列表)select 是否处于活动状态(真或假)。
在我的主子中,我只有一个
Allocator.show
command,你可能已经猜到了,allocator是我的用户名。
然后我一直在尝试一些事情,所以我不知道其余的用户表单代码有多正确;
Private Sub cbGo_Click()
Unload Allocator
End Sub
Private Sub cboxAlison_Click()
If Me.cboxAlison.Value = True Then
AlisonYN = True
Else
AlisonYN = False
End If
End Sub
Private Sub cboxBeverly_Click()
If Me.cboxBeverly.Value = True Then
BevelyYN = True
Else
BevelyYN = False
End If
End Sub
Private Sub cboxCallum_Click()
If Me.cboxCallum.Value = True Then
CallumYN = True
Else
CallumYN = False
End If
End Sub
Private Sub cboxEllen_Click()
If Me.cboxEllen.Value = True Then
EllenYN = True
Else
EllenYN = False
End If
End Sub
Private Sub cboxGeoff_Click()
If Me.cboxGeoff.Value = True Then
GeoffYN = True
Else
GeoffYN = False
End If
End Sub
Private Sub cboxJames_Click()
If Me.cboxJames.Value = True Then
JamesYN = True
Else
JamesYN = False
End If
End Sub
Private Sub cboxLouise_Click()
If Me.cboxLouise.Value = True Then
LouiseYN = True
Else
LouiseYN = False
End If
End Sub
Private Sub cboxMick_Click()
If Me.cboxMick.Value = True Then
MickYN = True
Else
MickYN = False
End If
End Sub
Private Sub cboxTammy_Click()
If Me.cboxTammy.Value = True Then
TammyYN = True
Else
TammyYN = False
End If
End Sub
Private Sub tbRPName_Change()
End Sub
Private Sub UserForm_Initialize()
Dim GeoffYN, TammyYN, CallumYN, JamesYN, MickYN, AlisonYN, BeverlyYN, LouiseYN, EllenYN As Boolean
Dim RP_Name As String
Me.cboxGeoff.Value = True
Me.cboxTammy.Value = True
Me.cboxCallum.Value = True
Me.cboxJames.Value = True
Me.cboxMick.Value = False
Me.cboxAlison.Value = False
Me.cboxBeverly.Value = False
Me.cboxLouise.Value = False
Me.cboxEllen.Value = False
Me.tbRPName = ""
End Sub
所有命名的用户变量 (xxxxYN) 在我的主模块中 public。
这些是我想在用户选中所需的框后将变量作为 true 或 false 拉回到我的主宏中,以及作为字符串的名称,然后继续 运行 原始宏。
任何帮助将不胜感激,我现在似乎在兜圈子!
PS 如果有帮助,我的用户表单如下所示;
干杯,
卡勒姆
我不知道实际问题是什么,但我试图重现你的问题,只是决定向你展示我所拥有的。看看这些是否对您有帮助。
所有这些代码都在用户窗体代码中,而不是在模块级别。当我更改复选框值时,这些值将被存储(在主子之外,在 "check" 子单击事件中验证)。
为了让你的代码更短一些,你可以直接将复选框的值赋给一个变量
Dim test as Boolean
test = me.CheckBox1.Value
您可以将其插入到您的转到按钮的代码中
你写了 "All of the named user variables (xxxxYN) are public in my main module." 但我们也看到它们在用户窗体的 Sub UserForm_Initialize
中声明:
Private Sub UserForm_Initialize()
Dim GeoffYN, TammyYN, CallumYN, JamesYN, MickYN, AlisonYN, BeverlyYN, LouiseYN, EllenYN As Boolean
Dim RP_Name As Stringn
...
即使您在任何模块中声明了与 Public
相同的变量,用户窗体变量也会隐藏它们的 Public namsakes 因此任何用户窗体设置都不是 "seen" 在其他模块中
所以你最好去掉"namesakes"的Userform调光语句,只留下Public
一个
此外,在您使用的声明语句中,每个未与特定类型明确关联的变量都隐式关联到 Variant 类型
所以在主模块中你应该使用如下的 "dimming" 语句:
Public GeoffYN As Boolean, TammyYN As Boolean, CallumYN As Boolean, JamesYN As Boolean, MickYN As Boolean, AlisonYN As Boolean, BeverlyYN As Boolean, LouiseYN As Boolean, EllenYN As Boolean
但是如果上面的所有内容都能让您继续,我还是建议您切换到 "class" 方法并使用 Dictionary 对象,如下所示
在 Allocator
代码窗格中放置以下代码
Option Explicit
Dim chkBoxes() As ChkBx_Class 'array of type "ChkBx_Class" which you define in a Class Module
Private Sub UserForm_Initialize()
Dim nControls As Integer, i As Integer
Dim namesArray As Variant, cbIniValues As Variant
UFInit = True
namesArray = Array("Geoff", "Tammy", "Callum", "James", "Mick", "Alison", "Beverly", "Louise", "Ellen") '<== set here the names to be associated to every CheckBox
cbIniValues = Array(True, True, True, True, False, False, False, False, False) '<== set here the initial values of checkboxes
nControls = UBound(namesArray) + 1 '<== retrieve the number of CheckBoxes you're going to consider in the Form
ReDim chkBoxes(1 To nControls) As ChkBx_Class 'redim the "ChkBx_Class" array
For i = 1 To nControls
Set chkBoxes(i) = New ChkBx_Class 'initialize a new instance of 'ChkBoxClass' class and store it in the array i-th position
With chkBoxes(i)
Set .ChkBox = Me.Controls("CheckBox" & i) 'assign the correct CheckBox control to its "ChkBox" property
.Name = namesArray(i - 1) ' assign the Name property of the Checkbox
.ChkBox.Value = cbIniValues(i - 1) 'set the checkbox correct initial value
Me.Controls("Label" & i) = .Name ' set the corresponding label caption
dealersDict.Add .Name, .ChkBox.Value ' fill the dictionary initial pair of Dealer-name/checkbox-value
End With
Next i
Me.tbRPName.Text = ""
UFInit = False
End Sub
Private Sub cbGo_Click()
Me.Hide
End Sub
向您的项目添加一个 "Class Module"
单击 VBA IDE 主功能区菜单中的插入-> Class 模块
或右键单击 VBA IDE 项目 Window 中的任意位置并 select 在后续子菜单中插入 -> Class 模块
展开项目中的"Class Module"节点Window
如果您没有看到项目 Window,您可以通过单击主功能区菜单中的查看-> 项目 Window 打开它,或者按 "Ctrl+R"
select你添加的新Class(应该是一些"Class1"之类的)并在属性中改名为"ChkBx_Class" Window "Name" 文本框
如果您没有看到 属性 Window,您可以通过单击主功能区菜单中的查看-> 属性 Window 或按 "F4"
在 Class 模块代码窗格中放置以下内容
Option Explicit
'declare class properties: they will be associated in every instance of this class.
Public WithEvents ChkBox As MSForms.CheckBox ' "ChkBox" is now a property of the class of type CheckBox. it's associated to events
Public Name As String
' events associated to ChkBox class property
Sub ChkBox_Click()
If Not UFInit Then dealersDict.Item(Me.Name) = Me.ChkBox.Value ' set the dictionary pair of Dealer-name/checkbox-value
End Sub
按如下方式编辑您的主要子模块
Option Explicit
Public dealersDict As New Scripting.Dictionary
Public UFInit As Boolean
Sub main()
myval = "io"
Dim myKey As Variant
Allocator.Show
Unload Allocator
For Each myKey In dealersDict
MsgBox myKey & ": " & dealersDict(myKey)
Next myKey
End Sub
创建对 Microsoft 脚本运行时库的引用以使用字典。
这是通过在 Visual Basic 编辑器 (VBE) 中选择工具 ➜ 参考命令来完成的,它会弹出一个对话框,您可以在其列表框中找到 "Microsoft Scripting Runtime" 接下来打上复选标记,然后按确定。
运行主副
每当您需要检索与给定 name 关联的布尔值时,您只需使用
myBool = dealersDict(name)
名称可以是:
具有所需名称的字符串文字 ("Alison", "Mick" , ..)
一个字符串变量,其值存储想要的名称,因此您可能在代码中的某处键入:
Dim name as string
name = "Mick"
这种方法为您提供了很大的灵活性,因为您只需:
在[=23=中的两个数组(namesArray
和cbIniValues
)中设置名称及其初始布尔值]
确保您有以 "CheckBox1"、"CheckBox2" 等命名的复选框,以及以 "label1"、"Label2" 命名的标签, 等等
确保 "CheckBoxX" 与 "LabelX"
对齐
确保 namesArray
和 cbIniValues
具有与标签和复选框相同的项目编号
早安,
我的项目 运行 遇到了一个小障碍。我是 VBA 的新手,正在尽最大努力 'learn by doing' 但我似乎无法理解 macro/userform 互动。
我有一个包含一个文本框和 9 个复选框的用户表单。这应该显示用户表单,允许用户指定 sheet 名称,以及(来自 9 个用户的列表)select 是否处于活动状态(真或假)。
在我的主子中,我只有一个
Allocator.show
command,你可能已经猜到了,allocator是我的用户名。
然后我一直在尝试一些事情,所以我不知道其余的用户表单代码有多正确;
Private Sub cbGo_Click()
Unload Allocator
End Sub
Private Sub cboxAlison_Click()
If Me.cboxAlison.Value = True Then
AlisonYN = True
Else
AlisonYN = False
End If
End Sub
Private Sub cboxBeverly_Click()
If Me.cboxBeverly.Value = True Then
BevelyYN = True
Else
BevelyYN = False
End If
End Sub
Private Sub cboxCallum_Click()
If Me.cboxCallum.Value = True Then
CallumYN = True
Else
CallumYN = False
End If
End Sub
Private Sub cboxEllen_Click()
If Me.cboxEllen.Value = True Then
EllenYN = True
Else
EllenYN = False
End If
End Sub
Private Sub cboxGeoff_Click()
If Me.cboxGeoff.Value = True Then
GeoffYN = True
Else
GeoffYN = False
End If
End Sub
Private Sub cboxJames_Click()
If Me.cboxJames.Value = True Then
JamesYN = True
Else
JamesYN = False
End If
End Sub
Private Sub cboxLouise_Click()
If Me.cboxLouise.Value = True Then
LouiseYN = True
Else
LouiseYN = False
End If
End Sub
Private Sub cboxMick_Click()
If Me.cboxMick.Value = True Then
MickYN = True
Else
MickYN = False
End If
End Sub
Private Sub cboxTammy_Click()
If Me.cboxTammy.Value = True Then
TammyYN = True
Else
TammyYN = False
End If
End Sub
Private Sub tbRPName_Change()
End Sub
Private Sub UserForm_Initialize()
Dim GeoffYN, TammyYN, CallumYN, JamesYN, MickYN, AlisonYN, BeverlyYN, LouiseYN, EllenYN As Boolean
Dim RP_Name As String
Me.cboxGeoff.Value = True
Me.cboxTammy.Value = True
Me.cboxCallum.Value = True
Me.cboxJames.Value = True
Me.cboxMick.Value = False
Me.cboxAlison.Value = False
Me.cboxBeverly.Value = False
Me.cboxLouise.Value = False
Me.cboxEllen.Value = False
Me.tbRPName = ""
End Sub
所有命名的用户变量 (xxxxYN) 在我的主模块中 public。
这些是我想在用户选中所需的框后将变量作为 true 或 false 拉回到我的主宏中,以及作为字符串的名称,然后继续 运行 原始宏。
任何帮助将不胜感激,我现在似乎在兜圈子!
PS 如果有帮助,我的用户表单如下所示;
干杯,
卡勒姆
我不知道实际问题是什么,但我试图重现你的问题,只是决定向你展示我所拥有的。看看这些是否对您有帮助。
所有这些代码都在用户窗体代码中,而不是在模块级别。当我更改复选框值时,这些值将被存储(在主子之外,在 "check" 子单击事件中验证)。
为了让你的代码更短一些,你可以直接将复选框的值赋给一个变量
Dim test as Boolean
test = me.CheckBox1.Value
您可以将其插入到您的转到按钮的代码中
你写了 "All of the named user variables (xxxxYN) are public in my main module." 但我们也看到它们在用户窗体的 Sub UserForm_Initialize
中声明:
Private Sub UserForm_Initialize()
Dim GeoffYN, TammyYN, CallumYN, JamesYN, MickYN, AlisonYN, BeverlyYN, LouiseYN, EllenYN As Boolean
Dim RP_Name As Stringn
...
即使您在任何模块中声明了与 Public
相同的变量,用户窗体变量也会隐藏它们的 Public namsakes 因此任何用户窗体设置都不是 "seen" 在其他模块中
所以你最好去掉"namesakes"的Userform调光语句,只留下Public
一个
此外,在您使用的声明语句中,每个未与特定类型明确关联的变量都隐式关联到 Variant 类型
所以在主模块中你应该使用如下的 "dimming" 语句:
Public GeoffYN As Boolean, TammyYN As Boolean, CallumYN As Boolean, JamesYN As Boolean, MickYN As Boolean, AlisonYN As Boolean, BeverlyYN As Boolean, LouiseYN As Boolean, EllenYN As Boolean
但是如果上面的所有内容都能让您继续,我还是建议您切换到 "class" 方法并使用 Dictionary 对象,如下所示
在 Allocator
代码窗格中放置以下代码
Option Explicit
Dim chkBoxes() As ChkBx_Class 'array of type "ChkBx_Class" which you define in a Class Module
Private Sub UserForm_Initialize()
Dim nControls As Integer, i As Integer
Dim namesArray As Variant, cbIniValues As Variant
UFInit = True
namesArray = Array("Geoff", "Tammy", "Callum", "James", "Mick", "Alison", "Beverly", "Louise", "Ellen") '<== set here the names to be associated to every CheckBox
cbIniValues = Array(True, True, True, True, False, False, False, False, False) '<== set here the initial values of checkboxes
nControls = UBound(namesArray) + 1 '<== retrieve the number of CheckBoxes you're going to consider in the Form
ReDim chkBoxes(1 To nControls) As ChkBx_Class 'redim the "ChkBx_Class" array
For i = 1 To nControls
Set chkBoxes(i) = New ChkBx_Class 'initialize a new instance of 'ChkBoxClass' class and store it in the array i-th position
With chkBoxes(i)
Set .ChkBox = Me.Controls("CheckBox" & i) 'assign the correct CheckBox control to its "ChkBox" property
.Name = namesArray(i - 1) ' assign the Name property of the Checkbox
.ChkBox.Value = cbIniValues(i - 1) 'set the checkbox correct initial value
Me.Controls("Label" & i) = .Name ' set the corresponding label caption
dealersDict.Add .Name, .ChkBox.Value ' fill the dictionary initial pair of Dealer-name/checkbox-value
End With
Next i
Me.tbRPName.Text = ""
UFInit = False
End Sub
Private Sub cbGo_Click()
Me.Hide
End Sub
向您的项目添加一个 "Class Module"
单击 VBA IDE 主功能区菜单中的插入-> Class 模块
或右键单击 VBA IDE 项目 Window 中的任意位置并 select 在后续子菜单中插入 -> Class 模块
展开项目中的"Class Module"节点Window
如果您没有看到项目 Window,您可以通过单击主功能区菜单中的查看-> 项目 Window 打开它,或者按 "Ctrl+R"
select你添加的新Class(应该是一些"Class1"之类的)并在属性中改名为"ChkBx_Class" Window "Name" 文本框
如果您没有看到 属性 Window,您可以通过单击主功能区菜单中的查看-> 属性 Window 或按 "F4"
在 Class 模块代码窗格中放置以下内容
Option Explicit
'declare class properties: they will be associated in every instance of this class.
Public WithEvents ChkBox As MSForms.CheckBox ' "ChkBox" is now a property of the class of type CheckBox. it's associated to events
Public Name As String
' events associated to ChkBox class property
Sub ChkBox_Click()
If Not UFInit Then dealersDict.Item(Me.Name) = Me.ChkBox.Value ' set the dictionary pair of Dealer-name/checkbox-value
End Sub
按如下方式编辑您的主要子模块
Option Explicit
Public dealersDict As New Scripting.Dictionary
Public UFInit As Boolean
Sub main()
myval = "io"
Dim myKey As Variant
Allocator.Show
Unload Allocator
For Each myKey In dealersDict
MsgBox myKey & ": " & dealersDict(myKey)
Next myKey
End Sub
创建对 Microsoft 脚本运行时库的引用以使用字典。
这是通过在 Visual Basic 编辑器 (VBE) 中选择工具 ➜ 参考命令来完成的,它会弹出一个对话框,您可以在其列表框中找到 "Microsoft Scripting Runtime" 接下来打上复选标记,然后按确定。
运行主副
每当您需要检索与给定 name 关联的布尔值时,您只需使用
myBool = dealersDict(name)
名称可以是:
具有所需名称的字符串文字 ("Alison", "Mick" , ..)
一个字符串变量,其值存储想要的名称,因此您可能在代码中的某处键入:
Dim name as string name = "Mick"
这种方法为您提供了很大的灵活性,因为您只需:
在[=23=中的两个数组(
namesArray
和cbIniValues
)中设置名称及其初始布尔值]确保您有以 "CheckBox1"、"CheckBox2" 等命名的复选框,以及以 "label1"、"Label2" 命名的标签, 等等
确保 "CheckBoxX" 与 "LabelX"
对齐
确保
namesArray
和cbIniValues
具有与标签和复选框相同的项目编号