【问题标题】:VBA: Global Constant Strings [duplicate]VBA:全局常量字符串
【发布时间】:2019-04-24 22:00:29
【问题描述】:

我正在使用 Excel 中的数学特殊字符。
(指数⁴、GRΣΣK 和其他其他 Unicode 字符。)

我想将常用的 Unicode 字符串存储为全局常量,因为这可能比每次需要时都调用 CStr() 快得多(而且不易出错)。

例如,我在所有函数之外都有这些声明:

Public Const STRPOWER0        As String = CStr(ChrW(&H2070)) '0th power
Public Const STRPOWER1        As String = "¹" 'CStr(ChrW(&HB9)) 1st power
Public Const STRPOWER2        As String = "²" 'CStr(ChrW(&HB2)) 2nd power
Public Const STRPOWER3        As String = "³" 'CStr(ChrW(&HB3)) 3rd power
Public Const STRPOWER4        As String = CStr(ChrW(&H2074)) '4th power
Public Const STRPOWER5        As String = CStr(ChrW(&H2075)) '5th power
Public Const STRPOWER6        As String = CStr(ChrW(&H2076)) '6th power
Public Const STRPOWER7        As String = CStr(ChrW(&H2077)) '7th power
Public Const STRPOWER8        As String = CStr(ChrW(&H2078)) '8th power
Public Const STRPOWER9        As String = CStr(ChrW(&H2079)) '9th power
Public Const STRPOWERNEGATIVE As String = CStr(ChrW(&H207B)) 'Superscript negative sign

问题是,每当我尝试引用其中一个字符串时,其值为Empty
(如果我打开Option Explicit 我会收到Variable not defined 的错误)

我做错了什么?
VBA 不支持将全局常量作为字符串吗?

【问题讨论】:

  • 您的全局常量是否位于普通模块(不是代码、用户窗体、工作表或工作簿模块)中?您是否在使用 Option Private Module 然后尝试在不同的模块中使用这些常量?这些是否位于模块最顶部的声明区域中,就在Option Explicit 下方?
  • 在上面的基础上,我感觉你没有放在模块的声明区域,因为你不能使用函数将值设置为常量。 CStr()ChrW() 都是函数。
  • @K.Dᴀᴠɪs ... located in a normal module? 是的。 ... using Option Private Module?我不知道那是什么。我还没有使用我所知道的,但如果需要的话我可以吗? ... attempting to use these constants in a different module 不,只是在同一个模块中使用它们。 ... located at the very top 不,还有一些其他类型声明和其他一些函数。 ... can't use a function to set a value to a constant. 哦,是的,这可能是一个危险信号。我想这意味着我必须让它们成为“变量”,并且小心不要覆盖它们?
  • 因为它们被声明为Const,所以你不能覆盖它们

标签: excel vba global-variables excel-2019


【解决方案1】:

很遗憾,您不能使用函数将值设置为常量。 Const 的目的是常量的值在运行时之前设置,而函数只能在运行时返回值。

您的问题似乎是您的常量未在模块的declarations section 中声明,这就是为什么您在运行任何代码时都不会收到编译错误。

不过,还有一些替代方案。

您可以为每个变量创建一个函数:

Function STRPOWER0() As String
    STRPOWER0 = CStr(ChrW(&H2070))
End Function

Sub Main()
    Msgbox STRPOWER0
End Sub

您指出每次调用 STRPOWER0 时都会担心运行 CStr()ChrW() 函数。虽然您可能只会受到非常小的性能影响(即使多次调用),但您可以使用 Static 变量仅在运行时的第一次进行转换。

Function STRPOWER0() As String
    Static RetVal As String
    If RetVal = "" Then RetVal = CStr(ChrW(&H2070))
    STRPOWER0 = RetVal
End Function

Sub Main()
    Msgbox STRPOWER0
End Sub

静态允许变量 RetVal 在整个运行时期间保留其数据,即使函数超出范围也是如此。


另一种选择是在运行开始时使用 sub 设置所有变量:

'This line in declarations section of module
Public STRPOWER0$, STRPOWER1$, STRPOWER2$ ', etc

Private Sub SetPubVars

    STRPOWER0 = CStr(ChrW(&H2070))
    STRPOWER1 = CStr(ChrW(&HB9))
    STRPOWER2 = CStr(ChrW(&HB2))

    ' So on

End Sub

Sub MAIN()

    ' Set the values
    SetPubVars

    MsgBox STRPOWER0

End Sub

【讨论】:

  • 我听从了您的建议,现在一切正常!静态在我的情况下不起作用,因为有多个函数需要使用这些字符串值(而且我没有使用类,坚持使用过程编程)。因此,我使用了您的最终替代方案,并声明了非常量私有全局变量,并编写了一个子程序来初始化它们,然后在每个需要访问全局变量的函数的开头调用了 init sub。我添加了一个名为 GlobalsInitialized 的全局布尔变量,因此如果多次调用,我的初始化子将跳过分配。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-14
  • 2018-01-28
  • 2018-04-20
  • 1970-01-01
  • 2015-09-17
  • 2016-10-06
相关资源
最近更新 更多