39

我对 VBA 还很陌生,所以这可能是一个简单的问题,但在这里。

我想myArray在 VBA 中初始化整个数组,比如整数。我知道我可以通过这样的简单初始化来做到这一点:

Dim myArray
myArray = Array(1, 2, 4, 8)

但是如果数组很大,这很麻烦,我想将所有元素初始化为相同的值。理想情况下,它会是这样的:

myArray(:) = 0

我试过了,但编译器抱怨。然后我尝试myArray() = 0了它,它也抱怨了这一点。

谁能解释如何做到这一点,而不循环?如果可能的话,我想在一份声明中做到这一点。

澄清

我想将数组的每个元素初始化为某个初始值。Dim myArray(300) As Integer因此,例如,如果我有一个包含 300 个整数的数组,则所有 300 个元素都将具有相同的初始值(例如,数字 13)。

更多说明

我发现这个答案表明你可以用这样的变量来做到这一点:

Dim x As Double: x = 0

也许有一种方法可以稍微更新语法以使其适用于数组?

4

8 回答 8

29

这很容易,至少如果您想要一个基于 1 的 1D 或 2D 变体数组:

Sub StuffVArr()
    Dim v() As Variant
    Dim q() As Variant
    v = Evaluate("=IF(ISERROR(A1:K1), 13, 13)")
    q = Evaluate("=IF(ISERROR(A1:G48), 13, 13)")
End Sub

字节数组也不错:

Private Declare Sub FillMemory Lib "kernel32" Alias "RtlFillMemory" _
        (dest As Any, ByVal size As Long, ByVal fill As Byte)

Sub StuffBArr()
    Dim i(0 To 39) As Byte
    Dim j(1 To 2, 5 To 29, 2 To 6) As Byte
    FillMemory i(0), 40, 13
    FillMemory j(1, 5, 2), 2 * 25 * 5, 13
End Sub

您可以使用相同的方法填充其他数值数据类型的数组,但仅限于可以用单个重复字节表示的值:

Sub StuffNArrs()
    Dim i(0 To 4) As Long
    Dim j(0 To 4) As Integer
    Dim u(0 To 4) As Currency
    Dim f(0 To 4) As Single
    Dim g(0 To 4) As Double

    FillMemory i(0), 5 * LenB(i(0)), &HFF 'gives -1
    FillMemory i(0), 5 * LenB(i(0)), &H80 'gives -2139062144
    FillMemory i(0), 5 * LenB(i(0)), &H7F 'gives 2139062143

    FillMemory j(0), 5 * LenB(j(0)), &HFF 'gives -1

    FillMemory u(0), 5 * LenB(u(0)), &HFF 'gives -0.0001

    FillMemory f(0), 5 * LenB(f(0)), &HFF 'gives -1.#QNAN
    FillMemory f(0), 5 * LenB(f(0)), &H80 'gives -1.18e-38
    FillMemory f(0), 5 * LenB(f(0)), &H7F 'gives 3.40e+38

    FillMemory g(0), 5 * LenB(g(0)), &HFF 'gives -1.#QNAN
End Sub

如果你想在其他情况下避免循环,它会变得更加棘手。除非您的数组是 50K 或更大的条目,否则这并不值得。只需在循环中设置每个值,您就会足够快,正如我在之前的回答中谈到的那样。

于 2013-10-12T18:24:36.370 回答
12

您可以通过指定维度来初始化数组。例如

Dim myArray(10) As Integer
Dim myArray(1 to 10) As Integer

如果您正在使用阵列并且这是您的第一次,那么我建议您访问 Chip Pearson 的网站

这初始化什么?例如,如果我想将整个数组初始化为 13 怎么办?

当您想初始化 13 个元素的数组时,您可以通过两种方式进行

Dim myArray(12) As Integer
Dim myArray(1 to 13) As Integer

首先,数组的下限将从开始,0因此您可以在数组中存储 13 个元素。例如

myArray(0) = 1
myArray(1) = 2
'
'
'
myArray(12) = 13

在第二个示例中,您已经指定了下限,1因此您的数组以开头1并且可以再次存储 13 个值

myArray(1) = 1
myArray(2) = 2
'
'
'
myArray(13) = 13

如果您使用上述任何一种方法初始化数组,则数组中每个元素的值都等于0。要检查,请尝试此代码。

Sub Sample()
    Dim myArray(12) As Integer
    Dim i As Integer

    For i = LBound(myArray) To UBound(myArray)
        Debug.Print myArray(i)
    Next i
End Sub

或者

Sub Sample()
    Dim myArray(1 to 13) As Integer
    Dim i As Integer

    For i = LBound(myArray) To UBound(myArray)
        Debug.Print myArray(i)
    Next i
End Sub

评论跟进

所以,在这个例子中,每个值都是 13。所以如果我有一个数组 Dim myArray(300) As Integer,所有 300 个元素都将保持值 13

就像我提到的,AFAIK,没有直接的方法可以实现你想要的。话虽如此,这是一种使用工作表函数Rept创建重复的 13 字符串的方法。一旦我们有了那个字符串,我们就可以使用SPLITusing","作为分隔符。但请注意,这会创建一个变量数组,但可以用于计算。

另请注意,在以下示例中,myArray实际上将保存 301 个值,其中最后一个为空 - 您必须通过额外初始化此值或从操作sNum之前删除最后一个“,”来解决这一问题Split

Sub Sample()
    Dim sNum As String
    Dim i As Integer
    Dim myArray

    '~~> Create a string with 13 three hundred times separated by comma
    '~~> 13,13,13,13...13,13 (300 times)
    sNum = WorksheetFunction.Rept("13,", 300)
    sNum = Left(sNum, Len(sNum) - 1)

    myArray = Split(sNum, ",")

    For i = LBound(myArray) To UBound(myArray)
        Debug.Print myArray(i)
    Next i
End Sub

在计算中使用变量数组

Sub Sample()
    Dim sNum As String
    Dim i As Integer
    Dim myArray

    '~~> Create a string with 13 three hundred times separated by comma
    sNum = WorksheetFunction.Rept("13,", 300)
    sNum = Left(sNum, Len(sNum) - 1)

    myArray = Split(sNum, ",")

    For i = LBound(myArray) To UBound(myArray)
        Debug.Print Val(myArray(i)) + Val(myArray(i))
    Next i
End Sub
于 2013-10-12T17:21:35.403 回答
4

我想将数组的每个元素初始化为某个初始值。因此,如果我有一个数组 Dim myArray(300) As Integer of 300 个整数,例如,所有 300 个元素将保持相同的初始值(例如,数字 13)。

谁能解释如何做到这一点,而不循环?如果可能的话,我想在一份声明中做到这一点。

我赢什么?

Sub SuperTest()
   Dim myArray
   myArray = Application.Transpose([index(Row(1:300),)-index(Row(1:300),)+13])
End Sub
于 2014-09-25T19:48:42.863 回答
3

对于 VBA,您需要分两行进行初始化。

Sub TestArray()

Dim myArray
myArray = Array(1, 2, 4, 8)

End Sub
于 2013-10-12T17:21:16.647 回答
2

此函数适用于大小和初始值的变量,它结合了 tbur 和 Filipe 响应。

Function ArrayIniValue(iSize As Integer, iValue As Integer)
Dim sIndex As String
sIndex = "INDEX(Row(1:" & iSize & "),)"
ArrayIniValue = Evaluate("=Transpose(" & sIndex & "-" & sIndex & "+" & iValue & ")")
End Function

这样调用:

myArray = ArrayIniValue(350, 13)
于 2015-05-12T17:02:35.997 回答
1

将@rdhs 答案放入函数中的好方法:

Function arrayZero(size As Integer)
  arrayZero = Evaluate("=IF(ISERROR(Transpose(A1:A" & size & ")), 0, 0)")
End Function

并像这样使用:

myArray = arrayZero(15)
于 2015-04-14T21:34:11.923 回答
0

感谢您的回答。我从 Matlab 重建了一些默认函数来初始化数组。

  • 冒号运算符作为函数
  • 空间
  • 那些

希望对任何应用程序都有帮助

Function colon( _
    ByVal LB As Integer, _
    ByVal UB As Integer, _
    Optional ByVal Step As Integer = 1, _
    Optional ByRef ColonStr As String = "")
'generates array from LB to UB with stepwidth Step
'equal to Matlab operator "a:b" or "a:n:b"

Dim sIndex As String
Cnt = WorksheetFunction.RoundUp((UB - LB + 1) / Step, 0)
sIndex = "INDEX(Row(1:" & Cnt & "),)"

ColonStr = "((Transpose(" & sIndex & ")-1)*" & Step & "+" & LB & ")"
colon = Evaluate("=" & ColonStr)
End Function


Function linspace( _
    ByVal LB As Integer, _
    ByVal UB As Integer, _
    Optional ByVal Count As Integer = 100)
'requirements: colon()
'generates linearly spaced array
'equal to Matlab function linspace()

Dim str As String
Count0 = Count - 1
temp = colon(0, Count0, 1, str)
y = Evaluate("=" & LB & "+" & str & "*" & ((UB - LB) / Count0))
linspace = "=" & LB & "+" & str & "*" & ((UB - LB) / Count0)
End Function


Function ones( _
    ByVal vert As Integer, _
    Optional ByVal horz As Integer = 1)
'generate array of all ones
'horz (multidimension) not implemented yet

Dim sIndex As String
sIndex = "INDEX(Row(1:" & vert & "),)"
ones = Evaluate("=Transpose(" & sIndex & ")*0+1")
End Function


Function zeros( _
    ByVal vert As Integer, _
    Optional ByVal horz As Integer = 1)
'generate array of all zeros
'horz (multidimension) not implemented yet

Dim sIndex As String
sIndex = "INDEX(Row(1:" & vert & "),)"
zeros = Evaluate("=Transpose(" & sIndex & ")*0")
End Function
于 2021-06-17T09:59:38.753 回答
-1

一个班轮通过更新的动态功能Sequence()

如果您处理新的动态SEQUENCE() 函数(与 Excel/MS 365 相比),您可以创建一个基于 1 的二维数组,其中包含指定的维度索引(例如 5 行、4 列),其中填充有顺序列表数字。

由于 OP 需要通过固定数值(例如 13 的第三个参数)初始化整个数组,您只需将增量步骤(最后一个参数)设置为 0:

Excel 函数 输入任何所需工作表单元格的以下公式将在溢出范围内显示数组结果:

=SEQUENCE(5,4,13,0)
 

在 VBA 过程中使用

也可以分配

  • a) 评估结果或
  • b) 工作表函数本身

到预先声明的数组:

    Dim myArray()           ' declare variant array

a) 评估

    myArray = [Sequence(5,4,13,0)]
    myArray = Evaluate("Sequence(5,4,13,0)")

b) 功能方法

    myArray = Worksheetfunction.Sequence(5,4,13,0)  ' or even: Application.Sequence
于 2021-06-17T20:27:20.953 回答