我制作了一个带有SpinButton和标签的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发布于 2015-09-06 16:35:24
要让Counter在用户表单中工作,同时在Module1中声明它,您需要在Module1中将它声明为Public。这为整个项目设置了范围。
我不认为有理由将任何变量放置在用户表单之外,而是让您的旋转月旋转器工作,并使用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代码模块中显式的选项下面,并将每个变量的Public替换为Private。那你就不需要Module1..。至少对于问题中所描述的。
注意:作为一个副作用,将您的任何变量放在Module1中作为公共变量(这是它们在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代码中创建和读取这个值,而这正是我的更新所做的。
发布于 2015-09-06 16:27:05
如果它们在子函数或函数中声明,则只能在该子函数或函数中使用。一旦你离开这个函数,它就消失了。
如果在模块或窗体级别声明它们,则可以访问整个模块或窗体。
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你的代码的顶端。
https://stackoverflow.com/questions/32425301
复制相似问题