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
时,是潜在的性能杀手。你知道循环要迭代多少次,所以一定要在循环之外进行。然后您只需调整数组的大小一次,而不需要保留