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

Vba 具有在过程结束后持续存在的局部变量,vba,variables,encapsulation,local-variables,Vba,Variables,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 myFunction()
   Dim runCount As Integer

   runCount = runCount +1

   debug.print "This function is now running for the " & runCount & " time."
End Function
在本例中,代码不起作用,因为每次都会重置运行计数。当然,最简单的解决方案是声明一个全局变量,但在某些情况下,出于简单、封装或其他原因,我希望避免这样做


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

使用
Static
关键字来声明局部变量,而不是
Dim
,并且变量的内容将比调用它在其中声明的过程更有效

e、 g.这将按预期工作:

Function myFunction()
   Static runCount As Integer

   runCount = runCount + 1

   debug.print "This function is now running for the " & runCount & " time."
End Function
当变量仅在局部范围内有意义或仅在一个过程中使用时,使用
静态
局部变量可能比声明模块范围变量更可取


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

Option Explicit
Private foo As Long
使用
Private
(或
Dim
,但我更喜欢保留
Dim
来声明局部变量)或
Public
关键字来声明模块范围变量。
Global
关键字已弃用,其作用与
Public
完全相同


同样,VBA还支持
静态
成员

见此签名:

Function myFunction()
隐式地是
Public
成员。这将是明确的:

Public Function myFunction()
VBA支持在过程级别添加
Static
修饰符,因此您可以执行以下操作:

Public Static Function myFunction()

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

不要使用
静态
(imo)。
最好在模块级使用
专用
,而不是在模块级使用。

但更可取的做法是将计数器传递给函数
ByRef

将其设为公共变量,并在模块顶部声明。不要在子函数内部重新声明。您也可以将
静态运行计数作为整数执行
是,但这样做也会使它从函数外部可访问。我希望它只能在内部访问。这不是“如何声明全局变量”的重复,他特别询问如何持久化局部变量。正如@CallumDA所说,这可以通过在函数中声明它为
Static
来实现。你能解释一下为什么
Public
global优于
Static
?这似乎违背了这个时代流行的常识。无论如何,我也不太喜欢
Static
,因为它干扰了我在VBA和.NET之间的持续上下文切换,而
Static
的意思完全不同-但我没有提到它,因为这是未经证实的观点,而且,有时它是工作的正确工具。正如我在自己的回答中所说的,它可以说比在模块范围内声明更好。我会热情地向你推荐你的答案,用一些论据来支持你的主张。我不认为将以前的局部变量暴露在它所在的模块之外有什么意义。为什么
Public
?@FreeMan因为你减去了我,所以我更愿意听你讲关于Global上的prevalation Static。然而,有两个主要原因(适用于本案)。首先,作者的技能很低,因为他不懂静态。第二个问题是,程序级的静态代码在其他代码中容易丢失。关于第一个原因——这非常重要。第三,有很多关于静态和全局的讨论。您可以自由进行rtfm并制作您自己的imo。别忘了-我将其标记为imo,并将其标记为首选第3页。@Mathieu Guindon谢谢。公众是打字错误。当然是模块级的隐私……讽刺的是,@user6698332,我没有否决你的答案。此外,OP在他的问题中明确指出,“当然,最简单的解决方案是声明一个全局变量,但在某些情况下,出于简单性、封装性或其他原因,我希望避免这样做。”在回答问题时,用“你应该做你刚才说的你不想做的事情”,但没有给出充分的理由(超出“我的意见”)这不是一个特别好的答案。不幸的是,当提示您尝试改进您的答案时,您只是出于防御,现在可能会怒气冲冲地离开。很高兴听到如何改进此答案,@downvoter。值得一提的是,在我看来,通过将
Static
关键字移动到方法声明中,所有local变量(传递给函数并在方法体中)保留它们的值。@KostasK。好的一点-我倾向于首先尝试避免
静态
局部变量,但是…在我看来,一个
静态
过程是一件坏事,它会使局部变量隐式地静态(你可能知道我有多“喜欢”它)VBA的隐含功能!),所以…我会更新您的评论,并将其从我的答案中删除=)Mathieu,非常感谢,这正是我一直在寻找的。但你能详细解释一下最后的评论吗?使用Static是如何使局部变量隐式地保持静态的,为什么这样做不好?@JR它本质上是一种语言特性:如果
Static
修饰符应用于一个过程,那么该过程中的每个局部变量都隐式地
Static
,所以你有本地的
dimfoo,只要它是静态的,即使它没有明确地这样说。在我看来,这很容易出现bug,因为正如您现在所知道的,静态局部变量会在两个过程之间保留它们的值