Arrays 如何在excel vba中创建没有设置限制的数组?

Arrays 如何在excel vba中创建没有设置限制的数组?,arrays,excel,vba,Arrays,Excel,Vba,我想使用数组创建一个数字列表,但我不想知道最后一个数字,而是取决于其他因素,例如,你问用户上限是多少,数组将停在那里 我创建了一个数组,该数组将生成一个数字列表,但当结束数字已知时,例如: Sub makearray50() 'creates a list of numbers from 1 to 50 Dim i As Integer Dim theArray(1 To 50) As Double For i = 1 To 50 the

我想使用数组创建一个数字列表,但我不想知道最后一个数字,而是取决于其他因素,例如,你问用户上限是多少,数组将停在那里

我创建了一个数组,该数组将生成一个数字列表,但当结束数字已知时,例如:

Sub makearray50() 'creates a list of numbers from 1 to 50

    Dim i As Integer
    Dim theArray(1 To 50) As Double
        For i = 1 To 50
            theArray(i) = Int(0 + i)
        Next i
        For i = 1 To 50
            Sheets("ARRAY").Cells(i, 1).Value = theArray(i)
        Next i
End Sub
所以我想我会尝试一个未知的上限,这就是我尝试的:

Sub makearrayx() 'creates a list of numbers from 1 to x

    Dim i As Integer
    Dim x As Integer
    x = 10
    Dim theArray(1 To x) As Double
        For i = 1 To x
            theArray(i) = Int(0 + i)
        Next i
        For i = 1 To x
            Sheets("ARRAY").Cells(i, 1).Value = theArray(i)
        Next i
End Sub
我想,通过尝试使用x“已知”,我可以编辑它并询问用户希望x是什么(使用输入框),但VBA不允许,我得到错误消息:


下面是一个快速示例,说明如何重新对数组进行尺寸标注:

Sub test()
Dim i&
Dim theArray()
Dim cel As Range

i = 0

For Each cel In Range("A1:A28")
    ReDim Preserve theArray(i) 'This will resize the array, but keep previous values
    theArray(i) = cel.Value
    i = i + 1
Next cel

For i = LBound(theArray) To UBound(theArray) 'this will just show you the array is working in the Immediate Window
    Debug.Print theArray(i)
Next i

End Sub
在我的示例中,我将行号放在A1:A28中。它每次都会正确地增加数组大小。您可以通过添加
If
语句、(
If cel.value=“Gotham”然后数组(i)=cel.value
)或其他有助于确定数组大小的方法来实现这一点


或者,如果您想保留您的示例,并预先设置数组大小,您可以。假设我有A列,但数据大小(行数)总是变化的。您可以将数组大小设置为,例如,
Application.WorksheetFunction.Counta(Range(“A:A”))
,以获取可用于调整数组大小的非空单元格数。

您可以创建一个函数来返回此类数组:

Function MakeArray(n As Long) As Variant
    'Creates a 1-based array containing the values
    '1,2,...,n

    Dim A As Variant, i As Long
    ReDim A(1 To n)
    For i = 1 To n
        A(i) = i
    Next i

    MakeArray = A
End Function
注意我如何使用
Long
而不是
Integer
。电子表格中有超过一百万行,使用
Integer
迟早会导致溢出错误。还请注意,不需要将
A
声明为数组。变体可以保存数组,并且
ReDim
语句使其成为数组

您可以通过以下方式进行测试:

Sub test()
    Dim theArray As Variant, n As Long, i As Long
    n = InputBox("How many elements")
    theArray = MakeArray(n)
    For i = 1 To n
        Cells(i, 1).Value = theArray(i)
    Next i
End Sub

最后,如果您的数组一直在动态增长,那么重构代码使其使用集合可能更有意义,因为集合是VBA最接近内置动态列表数据结构的集合

这里是最简单的方法。该小组将:

->向用户询问数组的上限
->创建一个数组
->将值打印到工作表

Sub makearrayx()

    Dim i, x As Integer
    Dim theArray As Variant

    x = InputBox("Tell me array limit")

    ReDim theArray(1 To x)
    For i = 1 To x
        theArray(i) = i
    Next

    For i = 1 To x
        Sheets("ARRAY").Cells(i, 1).Value = theArray(i)
    Next

End Sub

也可以
ReDim Preserve
在添加阵列时保留阵列。它上面有一个SO线程和页面。还有,你是如何给输入框编码的?它们应该能够被使用。另外--
Int(0+i)
i
已经是一个整数时,它有什么意义?借用@JohnColeman的问题-为什么还要在数字上加
0
?你在想什么?我不确定我是否信任循环中的
ReDim Preserve
。除非VBA解释器为数组的增长分配空间,否则在将所有保留元素复制到新分配的数组中时,通过循环的次数将是二次的。有时,我所做的是分配比我需要的更多的资源,然后在循环后使用
ReDim Preserve
将其缩减为大小。当然,只有当循环中的通过次数有一个已知的上限时,这才有效。@JohnColeman-这很有趣!我不知道
Preserve
会这么敏感。因此,如果你做了
myArray(100)
然后加载数据,比如说只有90个值,那么你就可以做(最后,当你添加完数组后)
ReDim Preserve myArray(90)
?我非常肯定
ReDim Preserve
可以缩小数组,也可以增加数组。我同意@johncolman,因为
ReDim
,尤其是在添加
Preserve
时,是潜在的性能杀手。你知道循环要迭代多少次,所以一定要在循环之外进行。然后您只需调整数组的大小一次,而不需要保留