具有在过程结束后持久存在的局部变量

J R*_*J R 3 variables vba encapsulation local-variables

我不确定之前是否曾经问过,但我找不到它.假设我有一个带有局部变量的过程.通常,该函数在函数完成运行后会被销毁.但在某些情况下,我希望它能够持久存在,就像在这个例子中一样:

Function myFunction()
   Dim runCount As Integer

   runCount = runCount +1

   debug.print "This function is now running for the " & runCount & " time."
End Function
Run Code Online (Sandbox Code Playgroud)

在此示例中,代码不起作用,因为每次都会重置runCount.当然,最简单的解决方案是声明一个全局变量,但在某些情况下,我想为了简单,封装或其他原因而避免这种情况.

那么,在程序运行完成后,有没有办法让局部变量保持不变?

Mat*_*don 8

使用Static关键字来声明您的局部变量,而不是Dim,并且变量的内容将比对其声明的过程的调用寿命更长.

例如,这将按预期工作:

Function myFunction()
   Static runCount As Integer

   runCount = runCount + 1

   debug.print "This function is now running for the " & runCount & " time."
End Function
Run Code Online (Sandbox Code Playgroud)

Static当变量仅在局部范围内有意义或仅在一个过程中使用时,使用locals可能比声明模块范围变量更可取.


请注意,模块范围不等于全局范围.此变量可在其声明的模块中的任何位置访问,但不能在其外部访问:

Option Explicit
Private foo As Long
Run Code Online (Sandbox Code Playgroud)

使用Private(或Dim,但我更喜欢保留Dim声明本地)或Public关键字来声明模块范围变量.该Global关键字已弃用,与其完全相同Public.


正如Kostas K.正确指出的那样,VBA也支持Static成员.

看到这个签名:

Function myFunction()
Run Code Online (Sandbox Code Playgroud)

隐含地是Public成员.这将是明确的:

Public Function myFunction()
Run Code Online (Sandbox Code Playgroud)

VBA支持Static在过程级别添加修饰符,因此您可以这样做:

Public Static Function myFunction()
Run Code Online (Sandbox Code Playgroud)

现在你有一个Public函数,其中每个局部变量都是隐式的Static.这是太隐含的,容易出错的东西,为了我个人的口味,所以我会避免它.但如果你需要,知道它就在那里可能会很好.

  • 值得一提的是,通过将`Static`关键字移动到方法声明中,所有局部变量(传递给函数和方法体内)都保留了它们的值. (2认同)
  • @KostasK.好点 - 我倾向于首先尝试避免使用`静态`本地人...虽然... IMO一个`静态'程序是一个邪恶的东西,使本地人*隐含*静态(你可能知道我有多"爱"了隐含的东西VBA呢!),所以......我会提出你的意见并将其从我的答案中删除=) (2认同)
  • @JR它本质上是一个语言特性:如果将`Static`修饰符应用于一个过程,那么该过程中的每个局部变量都是隐式的"静态",所以你有本地的`Dim foo As Long`即使它没有静态也是静态的明确地这么说.容易出错的IMO,因为你现在知道的静态本地化在程序调用之间保留了它们的价值.最后一点,您的`Function`也隐式返回`Variant`.您将要声明一个`As [Type]`返回类型,并指定其返回值`myFunction = result`,以便调用者可以使用该返回值. (2认同)