在VBA中声明和初始化字符串数组

166

根据另一个Stack Overflow的帖子,这应该可以工作,但事实并非如此:

Dim arrWsNames As String() = {"Value1", "Value2"}

有没有人能告诉我错在哪里?


42
提示:花括号语法在VBA中不起作用,它是为VB.NET设计的。出于您自己的心理健康着想,请不要混淆这两个环境。 - boomer57
4
如果你正在使用Excel(并且对变体数组感到满意),你可以使用Dim x() As Variant: x = [{"Value1", "Value2"}] - ThunderFrame
3
如果有人看到这条评论,大概是两年后(就像我一样)。似乎VBA / Excel不喜欢使用变量的语法 Dim x() As Variant: x = [{"Value1", "Value2"}]。 如果你使用变量,即如果 v1 =" Value1"; v2 =" Value2",那么 x = [{v1,v2}] 将会生成一个错误,而 x = [{"Value1","Value2"}] 则不会。 - Chip R.
这个回答解决了你的问题吗?Microsoft Visual Basic:如何初始化数组变量? - sancho.s ReinstateMonicaCellio
8个回答

212

试试这个:

' Variant array    
Dim myVariantArray As Variant
myVariantArray = Array("Cat", "Dog", "Rabbit")

' String array
Dim myStringArray() As String
myStringArray = Split("Cat,Dog,Rabbit", ",")

24
技术上来说,它创建的是变体数组,而非字符串数组。当然,该变体数组可能仅由字符串组成,但这种方法也可以允许非字符串数据类型:myArray = Array("A", "B", 12345, "D"...) - David Zemens
12
Dim myStringArray() As String是定义一个字符串数组的语句,myStringArray = Array( "Cat", "Dog" , "Rabbit")则是将该数组初始化为包含三个元素的字符串数组,分别为"Cat"、"Dog"和"Rabbit"。"Variants - yuck!"是表达对变量类型Variant的厌恶情绪。 - Andez
35
如果您想将内容放在一行中,可以在声明后使用冒号:Dim arrWsNames() As String: arrWsNames = Split("Value1,Value2", ",")。上面的注释中的初始化对我没有用,因为Array()创建的是一个Variant数组而不是字符串数组。 - Andrej Sramko
8
不是一个好的答案,因为1)它是包含数组的变体,2)在VBA中,变体是最慢的数据类型。 - stifin
4
@stifin和3)VBA没有字符串数组初始化器。但是你可以使用Split函数,例如。 - Eldar Agalarov
显示剩余6条评论

177

对于字符串数组的特定情况,您可以使用Split Function初始化该数组,因为它返回的是字符串数组而不是变体数组:

Dim arrWsNames() As String
arrWsNames = Split("Value1,Value2,Value3", ",")

这样可以避免使用Variant数据类型,同时保留arrWsNames所需的类型。


5
这绝对能使传递给其他函数的过程更简洁,更重要的是能节省内存空间。 - Jason R. Mick

33

问题在于数组的长度未定义,如果将数组明确定义为字符串,这会使VBA混淆。然而,变量似乎可以根据需要调整大小(因为它们占用了大量内存,人们通常出于很多原因而避免使用它们)。

以下代码完全正常运行,但与其他语言相比有点过时:

Dim SomeArray(3) As String

SomeArray(0) = "Zero"
SomeArray(1) = "One"
SomeArray(2) = "Two"
SomeArray(3) = "Three"

1
所以在数组声明中,我们不定义大小(4),而是最高索引(3)? 我理解得对吗? - dpelisek

6
Public Function _
CreateTextArrayFromSourceTexts(ParamArray SourceTexts() As Variant) As String()

    ReDim TargetTextArray(0 To UBound(SourceTexts)) As String
    
    For SourceTextsCellNumber = 0 To UBound(SourceTexts)
        TargetTextArray(SourceTextsCellNumber) = SourceTexts(SourceTextsCellNumber)
    Next SourceTextsCellNumber

    CreateTextArrayFromSourceTexts = TargetTextArray
End Function

例子:

Dim TT() As String
TT = CreateTextArrayFromSourceTexts("hi", "bye", "hi", "bcd", "bYe")

结果:

TT(0)="hi"
TT(1)="bye"
TT(2)="hi"
TT(3)="bcd"
TT(4)="bYe"

享受吧!

编辑: 我删除了重复文本删除功能,并使代码更小更易于使用。


1
这应该是答案 - 尽管没有内置的初始化方式,但是像这样的全局函数肯定可以使代码易读,并且它不会强制要求你的定义必须是variant - Andez

6
Dim myStringArray() As String
*code*
redim myStringArray(size_of_your_array)

然后你可以像这样做一些静态的事情:
myStringArray = { item_1, item_2, ... }

或者类似这样的迭代方式:
Dim x
For x = 0 To size_of_your_array
    myStringArray(x) = data_source(x).Name
Next x

2

这是一个仅提取所需内容的函数,它与array()函数类似,但返回字符串类型。在使用之前,您需要先将数组声明为字符串类型,如下所示:

Sub UseStringArray()

    Dim sample() As String
    sample = StringArray("dog", "cat", "horse")

End Sub

Function StringArray(ParamArray ArgList())

    ReDim tempArray(UBound(ArgList)) As String
    For i = 0 To UBound(ArgList)
        tempArray(i) = ArgList(i)
    Next
    StringArray = tempArray

End Function

更多有关转换数组类型的信息请参见此处:如何在VBA中将变体转换为双精度格式,反之亦然


我已经使用VBA超过20年了,但我不知道ParamArray的存在。你是一个巫师,谢谢! - Shodan

0

一种功能性方法

使用与 @matan_justme@mark_e 相同的解决方案,我认为可以清理结构。

就像内置函数 Array 一样,我们可以构建自己的自定义函数,使用 ParamArray 来接受作为参数的数组,并返回一个字符串数组。

默认情况下,将值分配给字符串数组时,它将隐式地将任何非字符串值转换为字符串。

Public Function StringArray(ParamArray values() As Variant) As String()
    Dim temp() As String
    ReDim temp(LBound(values) To UBound(values))

    Dim index As Long
    For index = LBound(temp) To UBound(temp)
        temp(index) = values(index)
    Next
    StringArray = temp
End Function

该结构的可重用性

这个结构的好处是可以应用于不同的数据类型,并使用直观的命名约定。例如,如果我们需要一个包含Long值的数组,只需更改每个实例中出现的String即可。

Public Function LongArray(ParamArray values() As Variant) As Long()
    Dim temp() As Long
    ReDim temp(LBound(values) To UBound(values))

    Dim index As Long
    For index = LBound(temp) To UBound(temp)
        temp(index) = values(index)
    Next
    LongArray = temp
End Function

其他数据类型的示例可能包括:

  • 单精度浮点型
  • 双精度浮点型
  • 日期型

美妙之处在于,当一个值不是正确的数据类型且无法转换时,会抛出一个错误,您将收到一个运行时错误'13':类型不匹配的错误。


-6

使用

Dim myarray As Variant

可以工作但是...

Dim myarray As String

不行,所以我坚持使用 Variant。


9
这是因为你应该在myarray的末尾添加括号。这些括号告诉VBA它是一个数组。将其声明为字符串会使其成为仅包含字符串的数组。 - PermaNoob
你必须声明数组的边界。可以使用动态数组:Dim MyArray() as String,或者使用固定大小的数组:Dim MyArray(1 to 10) as String - Patrick Lepelletier

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