我使用SpinButton和Label创建了一个Userform。当用户点击Spinup时,它会增加一个变量,然后将该索引从数组显示到标签。或者使用SpinDown的另一种方式。我一直遇到的问题是当我尝试使用模块中的变量来递增或递减以调整数组的索引时。我试过这种方式:
Private Sub SpinButtonM_SpinDown()
Dim Counter As Integer
Dim a As Integer
a = 1
Counter = Counter - a
UserForm2.Month.Caption = Counter
End Sub
我试过这种方式似乎都给了我错误:
Private Sub SpinButtonM_SpinDown()
Dim monthArray
monthArray = Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep",...)
Module1.Counter = Module1.Counter + 1
UserForm2.Month.Caption = Module.Counter
End Sub
答案 0 :(得分:2)
要在Module1中声明它时使Counter
在userform中工作,您需要在Module1中将其声明为Public。这为整个项目设定了范围。
我没有理由将任何变量放在userform之外,而是为了使你的循环月旋转器工作并使用Module1中的变量,这就是我要做的:
在Module1中,放置此代码:
Option Explicit
Public Counter As Long
Public monthArray As Variant
在userform中,放置以下代码:
Option Explicit
Private Sub SpinButtonM_SpinUp()
UpdateMonth 1
End Sub
Private Sub SpinButtonM_SpinDown()
UpdateMonth -1
End Sub
Private Sub UpdateMonth(Delta As Long)
Counter = Counter + Delta
If Counter < 1 Then Counter = 12
If Counter > 12 Then Counter = 1
Month = monthArray(Counter)
End Sub
Private Sub UserForm_Initialize()
monthArray = [transpose(text(date(,row(1:12),1),"mmm"))]
UpdateMonth 1
End Sub
注意:这假定Month
是标签的名称。
注意:不是使用Module1中的全局变量,而是在您的场景中将其范围限制为userform并将其声明为Private是更有意义的。您可以将它们直接放在userform代码模块中的Option Explicit下,并将Public
替换为每个变量的Private
。然后你不需要Module1 ......至少对于问题中描述的内容。
注意:作为将Module1中的任何变量设置为Public的副作用(这使得它们在userform中可用)关闭userform并不会结束程序。当您重新打开表单时,月份不会在Jan
上。相反,它将是用户窗体关闭时的位置,加上一个。要覆盖该行为,您需要向用户表单添加UserForm_Terminate()
过程并在其中放置End
语句。这将强制程序在用户窗体关闭时结束。但是,遵循将变量重新调整为用户形式的建议完全消除了这种副作用,这意味着您根本不需要UserForm_Terminate()
过程。
<强>更新强>
在回复您的注释时,要更改此解决方案以便在程序运行之间保留微调器显示的当前月份,即使工作簿已关闭然后重新打开,您也需要在每次微调器更改时保存当前月份。一种干净的方法是将Counter
值存储为命名常量。与任何已定义的名称一样,此命名常量可通过工作表中的名称管理器(Control-F3)进行检查。
请注意,我们存储的命名常量的名称是_CounterMemory
:
Private Sub SpinButtonM_SpinDown()
UpdateMonth -1
End Sub
Private Sub SpinButtonM_SpinUp()
UpdateMonth 1
End Sub
Private Sub UpdateMonth(Delta As Long)
Counter = Counter + Delta
If Counter < 1 Then Counter = 12
If Counter > 12 Then Counter = 1
Month = monthArray(Counter)
ThisWorkbook.Names.Add "_CounterMemory", Counter
End Sub
Private Sub UserForm_Initialize()
Dim n&
monthArray = [transpose(text(date(,row(1:12),1),"mmm"))]
On Error Resume Next
n = [_CounterMemory]
If n = 0 Then n = 1
Counter = n
UpdateMonth 0
End Sub
与将值存储在工作表中的单元格中相比,此路线的众多优点之一是自由裁量权。这是不合适的。它不容易受到正常的用户篡改,因为绝大多数普通用户不知道名称管理器。如果删除工作表,则不会对此解决方案产生任何影响。这是一种促进变量持久性的简洁方法。
作为澄清说明,命名常量与使用CONST语句在VBA模块中声明的常量不同。相反,命名常量类似于工作表上的命名范围,但不是命名范围,而是命名一个文字值(换句话说,一个常量值)。但我们可以从VBA代码中创建和读取该值,这正是我的更新所做的。
答案 1 :(得分:0)
如果它们在子或函数内声明,则只能在该子函数或函数中使用。一旦你离开这个功能,它就消失了。
如果您在模块或表单级别声明它们,则可以在整个模块或表单中访问它们。
Option explicit
Private strA as string
Sub test()
Dim strB As String
strA = "A"
strB = "B"
Test2
End Sub
Sub Test2()
msgbox strA
'msgbox strB This will not work as it is only available for sub test
End Sub
所以你可能想要移动
Dim Counter As Integer
到代码的最顶层。