VBA(Excel)初始化整个数组而不循环

时间:2013-10-12 17:15:55

标签: arrays excel vba excel-vba initialization

我对VBA来说相当新,所以这可能是一个简单的问题,但现在可以了。

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

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

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

myArray(:) = 0

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

任何人都可以解释如何执行此操作, 不循环 ?如果可能的话,我想在一个声明中这样做。

澄清

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

更多澄清

我发现this answer表示您可以使用如下变量执行此操作:

Dim x As Double: x = 0

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

8 个答案:

答案 0 :(得分:26)

这很容易,至少如果你想要一个基于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或更大的条目,否则不值得。只需在循环中设置每个值,就像我在earlier answer中谈到的那样,你将足够快

答案 1 :(得分:10)

您可以通过指定尺寸来初始化阵列。例如

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

如果您正在使用数组,如果这是您的第一次,那么我建议您访问Chip Pearson的WEBSITE

  

这是什么初始化的?例如,如果我想将整个数组初始化为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的方法。获得该字符串后,我们可以使用SPLIT作为分隔符使用","。但请注意,这会创建一个变量数组,但可以用于计算。

另请注意,在以下示例中,myArray实际上将保存301个值,其中最后一个为空 - 您必须通过另外初始化此值或从{移除最后一个“,”来解释该值在sNum操作之前{1}}。

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

答案 2 :(得分:4)

  

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

     

任何人都可以解释如何做到这一点,没有循环吗?我想这样做   在可能的情况下在一个声明中。

我赢了什么?

Sub SuperTest()
   Dim myArray
   myArray = Application.Transpose([index(Row(1:300),)-index(Row(1:300),)+13])
End Sub

答案 3 :(得分:1)

此功能适用于尺寸和初始值的变量,它结合了tbur& amp;菲利普的回应。

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)

答案 4 :(得分:0)

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

Sub TestArray()

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

End Sub

答案 5 :(得分:0)

将@rdhs答案放在函数中的奇特方法:

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

并像这样使用:

myArray = arrayZero(15)

答案 6 :(得分:0)

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

  • 冒号运算符作为函数
  • linspace

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

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

答案 7 :(得分:0)

通过更新的动态函数 Sequence()

的一个班轮

如果您处理新的动态 SEQUENCE() function(与 Excel/MS 365 相比) 您可以使用指定的维度索引(例如 5 行、4 列)创建一个基于 1 的二维数组 它被一个序列号列表填充。

因为 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