【问题标题】:Can an array be declared as a constant?数组可以声明为常量吗?
【发布时间】:2017-04-24 02:11:35
【问题描述】:

是否可以:

  1. 将数组声明为常量

  2. 使用变通方法声明一个数组,该数组可防止添加、删除或更改元素,因此在宏的生命周期内保持功能不变?

我当然可以这样做:

Const myConstant1 As Integer = 2
Const myConstant2 As Integer = 13
Const myConstant3 As Integer = 17
Const myConstant4 ...and so on

...但它失去了使用数组的优雅。我还可以将常量加载到一个数组中,并在每次使用它们时重新加载它们,但是在使用之前使用这些常量值重新加载数组的任何失败都可能将代码暴露给一个已更改的“常量”值。

欢迎任何可行的答案,但理想的答案是可以设置一次并且在修改其他代码时不需要任何更改/维护。

【问题讨论】:

    标签: arrays excel vba constants


    【解决方案1】:

    您可以使用函数返回数组并将函数用作数组。

    Function ContantArray()
        ContantArray = Array(2, 13, 17)
    End Function
    

    【讨论】:

    • 利用函数调用和数组调用的语法相同/不明确的事实......可爱!虽然应该是ConstantArray(错字!)。 (PS - 那是邪恶的!)
    • @ChrisB FWIW 该函数可能应该被相应地命名,即类似GetFooArray,这样它看起来就像一个函数调用 - 因为它就是这样。否则,如果没有Rubberduck,您将无法看到tell from the call sites
    • 我会避免在公共成员中使用下划线,但是是以动词开头的描述性内容。否则它只是误导(和邪恶!)
    • @ChrisB getRateMultipliers 会更好。 get 表示函数,复数表示数组。
    • 来到这里了解常量数组并发现了 join() 和 Rubberduck!
    【解决方案2】:

    我声明了"1,2,3,4,5"String 常量,然后使用Split 创建了一个新数组,如下所示:

    Public Const myArray = "1,2,3,4,5"
    
    Public Sub createArray()
    
            Dim i As Integer
            A = Split(myArray, ",")
    
            For i = LBound(A) To UBound(A)
                    Debug.Print A(i)
            Next i
    
    End Sub
    

    当我尝试在 A 上使用 ReDimReDim Preserve 时,它没有让我这样做。这种方法的缺点是你仍然可以编辑数组的值,即使你不能改变大小。

    【讨论】:

    • 如果您 Dim A() As String 可以在以后使用 ReDimReDim Preserve。这要求您强烈键入您的Const myArray As String = "1,2,3,4,5"
    • 天才解决我多年来遇到的问题。谢谢!!我对自己没有想到它感到失望。 :-( 每个人都建议使用函数而不是 const,但我希望能够在设计时像在 C/C++ 中那样维护我的数组。
    【解决方案3】:

    让它成为一个函数怎么样?如:

    Public Function myConstant(ByVal idx As Integer) As Integer
        myConstant = Array(2, 13, 17, 23)(idx - 1)
    End Function
    
    Sub Test()
        Debug.Print myConstant(1)
        Debug.Print myConstant(2)
        Debug.Print myConstant(3)
        Debug.Print myConstant(4)
    End Sub
    

    没有人可以更改它、调整它的大小或编辑它的内容...此外,您可以在一行中定义常量!

    【讨论】:

      【解决方案4】:

      如果特定的 VBA 环境是 Excel-VBA,则可以从 Excel 应用程序的 Evaluate 方法中获得一个很好的语法,该方法可以缩短为方括号。

      看看这个

      Sub XlSerialization1()
          Dim v
          v = [{1,2;"foo",4.5}]
      
          Debug.Assert v(1, 1) = 1
          Debug.Assert v(1, 2) = 2
          Debug.Assert v(2, 1) = "foo"
          Debug.Assert v(2, 2) = 4.5
      
          '* write all cells in one line
          Sheet1.Cells(1, 1).Resize(2, 2).Value2 = v
      End Sub
      

      【讨论】:

      • 这是此 Excel VBA 问题的正确答案。它应该有最多的选票并且是被接受的答案。
      • 我喜欢这种公式风格的语法!但是,遗憾的是,它不能用于常量const x = [{1,2,3}]
      【解决方案5】:

      如果不需要每次都新建一个实例,可以使用Static局部变量来避免创建和初始化多个对象:

      Private Function MyConstants()
          Static constants As Variant
      
          If IsEmpty(constants) Then
              constants = Array(2, 13, 17)
          End If
      
          MyConstants = constants
      End Function
      

      【讨论】:

        【解决方案6】:

        数组可以声明为常量吗?没有。

        解决方法 - 我能想到的最简单的方法是使用 delim 定义一个常量,然后使用 Split 函数创建一个数组。

        Const myConstant = "2,13,17"
        
        Sub Test()
            i = Split(myConstant, ",")
        
            For j = LBound(i) To UBound(i)
                Debug.Print i(j)
            Next
        End Sub
        

        【讨论】:

          【解决方案7】:

          是不是太简单了?

          PUBLIC CONST MyArray = "1,2,3,4"
          

          然后在模块中:

          Dim Arr as Variant
          
          SET Arr = split(MyArray,",")
          

          【讨论】:

          • 这个简单的解决方案对我有用。也可以将 Arr 定义为字符串数组(Dim Arr() as string)。
          【解决方案8】:

          我知道这是一个老问题,但这些档案在发布后通常会被扫描多年,所以我认为在原始日期之后很长时间添加内容没有问题。

          如何创建一个具有返回“数组”值的只读属性的类?您可以使用与数组索引相同的语法来指定参数,并且仅定义 GET 属性有效地使其只读。在类中定义常量值,它就像一个常量数组一样工作,即使实际构造不同。

          【讨论】:

            【解决方案9】:

            否 - 数组不能声明为常量,但您可以使用解决方法。

            你可以创建一个返回你想要的数组的函数

            http://www.vbaexpress.com/forum/showthread.php?1233-Solved-Declare-a-Constant-Array

            【讨论】:

            • 如果您在答案中显示了这样的功能,最好使用问题中的示例数据,并链接到该线程,我会给您一个赞成票;)
            • 这不是我的工作;它可能不值得赞成:-)。谷歌 30 秒!
            【解决方案10】:

            使用上述信息,我得出以下工作解决方案,用于比较一个月的短文本信息,独立于使用德语的 Excel:

            Const MONATE = ",Jän,Feb,März,Apr,Mai,Jun,Jul,Aug,Sep,Okt,Nov,Dez"

            .. 以及后面的代码:

                If StringToCompare = Split(MONATE, ",")(Month(dt)) Then
            

            注意:由于拆分数组从索引 0 开始,我在开头添加了逗号。

            【讨论】:

              【解决方案11】:

              不知道何时更改,但在 Excel 365 中,这有效(或者,至少不会产生编译器错误):

              Const table1Defs As Variant = Array("value 1", 42, Range("A1:D20"))
              

              【讨论】:

              • 不幸的是,即使没有 Range 引用,它也不能像最近的 Office 2016(我的是 32 位)(使用 Excel、Outlook 和 Access 测试)一样工作。
              猜你喜欢
              • 2011-04-17
              • 1970-01-01
              • 2011-05-09
              • 1970-01-01
              • 1970-01-01
              • 2015-06-16
              • 1970-01-01
              • 1970-01-01
              • 2017-10-09
              相关资源
              最近更新 更多