如何在VBA中声明一个数组变量?

25

我需要将变量添加到数组中

Public Sub Testprog()

Dim test As Variant
Dim iCounter As Integer

If test = Empty Then
    iCounter = 0
    test(iCounter) = "test"
Else
    iCounter = UBound(test)
End If
End Sub

test(iCounter) = "test" 处出现错误

请提供一些解决方案

7个回答

32

通常情况下,应该声明一个具体类型的变量,而不是使用Variant类型。在这个例子中,test变量应该是String类型。

另外,因为它是一个数组,你需要在声明变量时明确指出。有两种声明数组变量的方法:

  1. 如果在编写程序时知道数组的大小(即应该包含的元素数),则可以在声明中用括号指定该数字:

    Dim test(1) As String   'declares an array with 2 elements that holds strings
    

    这种类型的数组被称为静态数组,因为其大小是固定的。

  2. 如果在编写应用程序时不知道数组的大小,则可以使用动态数组。动态数组是指其大小未在声明中(Dim语句)指定,而是在程序执行期间使用ReDim语句确定的数组。例如:

  3. Dim test() As String
    Dim arraySize As Integer
    
    ' Code to do other things, like calculate the size required for the array
    ' ...
    arraySize = 5
    
    ReDim test(arraySize)  'size the array to the value of the arraySize variable
    

8
括号中的数字是数组的上限 UBound(),而不是大小。如果选项基础为0(默认值),则这些值将偏离1个单位。 - Caltor

11

除了Cody Gray的回答之外,还有第三种方法(这里的所有内容也适用):

您还可以使用动态数组,在运行时调整大小:

Dim test() as String
Dim arraySize as Integer

Do While someCondition
    '...whatever
    arraySize = arraySize + 1
    ReDim Preserve test(arraySize)
    test(arraySize) = newStringValue
Loop

注意Preserve关键字。如果没有它,重新调整数组大小还会初始化所有元素。


8
进一步回答RolandTumble对Cody Gray的回答,两个都很好的回答,这里提供另一种非常简单和灵活的方式,当您在编码时知道数组的所有内容 - 例如,您只想构建一个包含1、10、20和50的数组。这也使用了变量声明,但不使用ReDim。与Roland的答案一样,数组元素数量的枚举计数不需要特别知道,但可以通过使用uBound获得。
sub Demo_array()
    Dim MyArray as Variant, MyArray2 as Variant, i as Long

    MyArray = Array(1, 10, 20, 50)  'The key - the powerful Array() statement
    MyArray2 = Array("Apple", "Pear", "Orange") 'strings work too

    For i = 0 to UBound(MyArray)
        Debug.Print i, MyArray(i)
    Next i
    For i = 0 to UBound(MyArray2)
        Debug.Print i, MyArray2(i)
    Next i
End Sub

我喜欢这种创建数组的方式,比其他方式都更好。很棒的一点是你可以在数组语句中直接添加或删除元素,而不需要对代码做任何其他修改。要将"鸡蛋"添加到三个元素的食品数组中,只需在适当的位置键入 ", "鸡蛋",然后就完成了。你的食品数组现在有了四个元素,而且不需要修改 Dim,并且完全省略 ReDim。

如果不想使用基于 0 的数组 - 例如,使用 MyArray(0) - 一个解决方法就是将 0 或 "" 置于第一个元素。

请注意,这可能会被某些编码纯粹主义者视为不好的做法;一个公正的反对意见可能是"硬数据"应该在 Const 语句中,而不是在例程的代码语句中。另一个坏处可能是,如果你将 36 个元素放入一个数组中,则应该设置 const 为 36,而不是在无知中编写代码。后一个反对意见是有争议的,因为它要求维护 const 为 36,而不是依赖于 uBound。如果你添加了第37个元素但让 Const 保持为 36,则可能会出现问题。


我对上面的代码标签问题感到困惑 - 如果有人可以修复它,谢谢。如果你能解释一下它是如何格式错误的,再次感谢。 - MicrosoftShouldBeKickedInNuts
1
在 Stack Overflow 上,代码块是通过将每行缩进 4 个空格来格式化的。您还可以在编辑器中单击花括号图标。有关更多信息,请参阅 Stack Overflow 的格式帮助页面 - Brandon Anzaldi
1
谢谢Brandon,你的解释非常到位,那个链接也很棒。在你的编辑之后,现在这篇文章看起来很好。我希望你也能从我的帖子中受益 - 自从发现了这种方法,我再也不用费心去使用其他方式来创建VBA数组了。- MSBKIN - MicrosoftShouldBeKickedInNuts
我不建议这样做,除非你知道元素的确切数量和它们的值。 - Mark Walsh

6
正如其他人指出的那样,你的问题在于你没有声明一个数组。
下面我尝试重新创建你的程序,使其按照你的意图工作。 我尽量保留了原有的内容(例如将你的数组保留为变量)。
Public Sub Testprog()
    '"test()" is an array, "test" is not
    Dim test() As Variant
    'I am assuming that iCounter is the array size
    Dim iCounter As Integer

    '"On Error Resume Next" just makes us skip over a section that throws the error
    On Error Resume Next

    'if test() has not been assigned a UBound or LBound yet, calling either will throw an error
    '   without an LBound and UBound an array won't hold anything (we will assign them later)

    'Array size can be determined by (UBound(test) - LBound(test)) + 1
    If (UBound(test) - LBound(test)) + 1 > 0 Then
        iCounter = (UBound(test) - LBound(test)) + 1

        'So that we don't run the code that deals with UBound(test) throwing an error
        Exit Sub
    End If

    'All the code below here will run if UBound(test)/LBound(test) threw an error
    iCounter = 0

    'This makes LBound(test) = 0
    '   and UBound(test) = iCounter where iCounter is 0
    '   Which gives us one element at test(0)
    ReDim Preserve test(0 To iCounter)

    test(iCounter) = "test"
End Sub

2
你必须将数组变量声明为数组:
Dim test(10) As Variant

-1

大卫,出现错误:Microsoft Office Excel 已停止工作。有两个选项:在线查找解决方案并关闭程序,或者直接关闭程序。我确定错误在我的数组中,但我已经仔细阅读了所有内容,似乎这是定义数组的方法。


-4

数组索引只接受长整型数值。

你将 iCounter 声明为整数类型。你应该将它声明为长整型。


8
这完全不是真的。 - user2140173
整数和长整型可以互换使用,但仅在将长整型设为整数时会导致未定义行为,反之则不会。 - Mark Walsh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接