【问题标题】:Public Static variable in excel vbaexcel vba中的公共静态变量
【发布时间】:2014-03-15 09:52:55
【问题描述】:

是否可以在一个过程中声明一个静态变量,并使用 Excel VBA 在多个不同的过程中使用该变量?

Public myvar as integer

Sub SetVar()
   static myvar as integer
   myvar=999
end sub

sub Usevar()
    dim newvar as integer
    newvar=myvar*0.5
end sub

我需要 myvar 被其他程序看到,而不是改变或“丢失”。如果 myvar 未声明为静态变量,则上面的代码有效,但更多代码则变量“丢失”。如果使用静态声明,则 usevar 过程看不到 myvar。并且 VBA 不接受“Public Static myvar as integer”。

感谢您的帮助

宙斯

【问题讨论】:

  • 全局变量始终是静态的,因为它保持其值,除非代码执行停止。如果这就是您想要静态变量的原因,那么请使用全局变量。
  • 蒂姆,感谢您编辑我的帖子和您的回答。我要做的就是在一个模块的几个过程中初始化几个集合,然后在另一个模块的几个过程中使用这些集合。将它们声明为 Public 有帮助,但我现在有运行时错误 91 对象变量或未设置块变量,我不知道为什么。代码似乎运行正常,直到代码执行停止或代码更改。有没有像使用 set 语句一样让它更健壮?
  • 我通过在每次运行时都使用它们的过程中初始化集合来解决这个问题,但这似乎是一个糟糕的解决方案。
  • 如果您不喜欢您的解决方案,为什么不将其作为更新发布并征求建议?
  • Public Const myvar as integer = 999

标签: excel vba global-variables public shared


【解决方案1】:

通过调用 MAIN() 试试这个:

Public myvar As Integer

Sub MAIN()
    Call SetVar
    Call UseVar
End Sub

Sub SetVar()
    myvar = 999
End Sub

Sub UseVar()
    Dim newvar As Variant
    newvar = myvar * 0.5
    MsgBox newvar
End Sub

如果您声明一个项目 Static ,它的值将保留在过程或子程序中。
如果您声明一个项目 Public ,它的值将被保留它对其他程序也是可见的。

【讨论】:

  • 感谢 Gary 的学生。您的解决方案有效,但如果我更改代码,我会收到运行时 91 错误,提示对象变量或未设置块变量。我不确定这意味着什么。我需要在 usevar() 中设置集合吗? setvar 和 usevar 也在不同的模块中。
  • 通过更改代码我的意思是更改过程的行位置 - 只需将其移动到 ' 语句上方
  • 有没有比在每个过程中初始化集合更有效的方法来初始化集合?
  • Dim 在模块的最顶部设置 myvar 应该使其可用于该模块中的所有子程序和函数。将其设为 Public 也应该使其可用于其他模块......我不确定事件代码是否也可以“看到”它。
  • 谢谢,问题似乎是代码更改(仍在开发中)或出现错误并且所有变量都被重置时。那么也许在 usevar 过程中进行了某种类型的错误检查?如果集合为 null 则刷新?
【解决方案2】:

尽管@Gary 的学生在四年前回答了这个问题,但有一个细微的差别值得一提,因为解决方案可能取决于myvar 的数据类型。

首先,正如您在问题中指出的那样,Public Static myvar as Integer 不起作用,因为 Static 只允许在子函数或函数中使用。

正如@Patrick Lepelletier 对 OP 的 cmets 所述,您可以通过声明 Constant 来轻松解决此问题(假设您不需要动态更改它):Public Const myvar as Integer = 999。 (或者可能是Private Const myvar...

另一种选择是将myvar 声明为函数,而不是变量或常量,从而有效地将其转换为伪常量

Private Function myvar() as Integer
     Static intMyvar as Integer 
     intMyvar = 999
     myvar = intMyvar
End function

在这个myvar 是整数的简单示例中,伪常量方法显然是不必要的,并且会增加函数调用的开销。只需声明 Constant 即可完成工作。然而,只有当值是静态的并且不是对象时,使用常量才有效。如果myvar 是一个对象,例如Range,它将不起作用。在这种情况下,使用伪常量可能会很有用:

Private Function myvar() as Range
    Set myvar = Range("A1")
End Function

另一个优点是您可以使用函数内部的代码来检查某些条件并相应地为myvar 分配不同的值。

伪常量方法也可以与命名工作表范围相结合:如果单元格 A1 是一个命名范围,比如MyRange,那么你可以这样写:

Dim strMyString as String
strMyString = "MyRange"
Private Function myvar() as Range
    Set myvar = Range(strMyString)
End Function

现在可以在不破坏代码的情况下移动单元格 A1 的内容,因为如果您剪切和粘贴单元格,命名范围会随之而来。我发现这种方法在设计阶段很有用,因为事情往往在工作表中移动很多。

伪常量还有助于避免some problems 通常与全局(或模块级)变量相关联,这在大型项目中可能会成为问题。

【讨论】:

    【解决方案3】:

    关键是使用2个变量。在下面的代码中,myvar 是公共的,但不是静态的。 stvar 是静态的,但不是公共的。它的范围仅在 Main() 内。通过分配 myvar=stvar 和 stvar=myvar,它有效地创建了一个既是公共的又是静态的变量。该值被保留。

    Public myvar As String
    Sub Main() 'in module 1
    Static stvar As String
    myvar = stvar
    toInput
    stvar = myvar
    End Sub
    
    Sub toInput() 'in module2
    myvar = InputBox("enter something", "Input", myvar)
    End Sub
    

    【讨论】:

      猜你喜欢
      • 2015-03-19
      • 2011-09-23
      • 2021-03-27
      • 1970-01-01
      • 2015-10-27
      • 2015-12-02
      • 2012-02-03
      • 2015-04-07
      相关资源
      最近更新 更多