首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >试图在VBA Excel中找出变量范围?

试图在VBA Excel中找出变量范围?
EN

Stack Overflow用户
提问于 2015-09-06 15:45:01
回答 2查看 476关注 0票数 1

我制作了一个带有SpinButton和标签的Userform。当用户点击Spinup时,它会增加一个变量,然后将该索引从数组显示到标签。或者用SpinDown的另一种方式。我一直遇到的问题是,当我试图使用模块中的变量来增加或减少以调整数组的索引时。我试过这样做:

代码语言:javascript
复制
Private Sub SpinButtonM_SpinDown()
    Dim Counter As Integer
    Dim a As Integer

    a = 1
    Counter = Counter - a

    UserForm2.Month.Caption = Counter
End Sub

我试过这样做,这两种方法似乎都给我带来了错误:

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-06 16:35:24

要让Counter在用户表单中工作,同时在Module1中声明它,您需要在Module1中将它声明为Public。这为整个项目设置了范围。

我不认为有理由将任何变量放置在用户表单之外,而是让您的旋转月旋转器工作,并使用Module1中的变量,然后我将这样做:

在Module1中,放置以下代码:

代码语言:javascript
复制
Option Explicit

Public Counter As Long
Public monthArray As Variant

在userform中,放置以下代码:

代码语言:javascript
复制
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

代码语言:javascript
复制
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代码中创建和读取这个值,而这正是我的更新所做的。

票数 2
EN

Stack Overflow用户

发布于 2015-09-06 16:27:05

如果它们在子函数或函数中声明,则只能在该子函数或函数中使用。一旦你离开这个函数,它就消失了。

如果在模块或窗体级别声明它们,则可以访问整个模块或窗体。

代码语言:javascript
复制
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

所以你可能想搬家

代码语言:javascript
复制
Dim Counter As Integer

你的代码的顶端。

请看这里的一些信息,https://support.microsoft.com/en-us/kb/141693

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32425301

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档