Excel 如何实例化动态空数组并添加其第一个元素?

Excel 如何实例化动态空数组并添加其第一个元素?,excel,vba,Excel,Vba,我一直在尝试实例化一个空数组,我将在其中添加元素。出于某种原因,我的脚本在对空数组调用Ubound时抛出了一个错误。我不知道如何实例化一个空数组。。。以下是我得到的: Dim data_dates data_dates = Array("6/24/2019", "7/1/2019", "7/8/2019", "7/15/2019", "7/22/2019", "7/29/2019", "8/5/2019", "8/12/2019", "8/19/2019", "8/26/2019", "9/2

我一直在尝试实例化一个空数组,我将在其中添加元素。出于某种原因,我的脚本在对空数组调用
Ubound
时抛出了一个错误。我不知道如何实例化一个空数组。。。以下是我得到的:

Dim data_dates 
data_dates = Array("6/24/2019", "7/1/2019", "7/8/2019", "7/15/2019", "7/22/2019", "7/29/2019", "8/5/2019", "8/12/2019", "8/19/2019", "8/26/2019", "9/2/2019")
Dim site_dates

For date_iter = 1 To UBound(data_dates)
    If start_date <= data_dates(date_iter) And last_date <= data_dates(date_iter) Then
        MsgBox UBound(site_dates) '- LBound(site_dates) + 1
        site_dates(UBound(site_dates) + 1) = data_dates(date_iter)
    End If
Next date_iter
Dim数据\u日期
数据日期=数组(“2019年6月24日”、“2019年7月1日”、“2019年7月8日”、“2019年7月15日”、“2019年7月22日”、“2019年7月29日”、“2019年8月5日”、“2019年8月12日”、“2019年8月19日”、“2019年8月26日”、“2019年9月2日”)
暗淡的地点
对于日期=1到UBound(数据日期)

如果开始日期开始生长过程的一种方法:

Sub InTheBeginning()
    Dim site_dates() As Date, msg As String
    ReDim site_dates(1)

    For i = 1 To 10
        ReDim site_dates(1 To UBound(site_dates) + 1)
    Next i


    msg = LBound(site_dates) & vbCrLf & UBound(site_dates)
    MsgBox msg
End Sub

此变量是隐式
变量
。虽然
Variant
可以很好地保存数组,但它会初始化为
Variant/Empty
,这不是数组-这就是
UBound(site_dates)
抛出错误的原因:您试图获取
Variant/Empty
的上限,而VBA不知道如何处理它

这声明了
变量
项的动态数组:

Dim site_dates()
这就是说,一般来说,您应该避免调整数组的大小(使用
ReDim Preserve theArray(UBound(theArray)+1)的循环
在每次迭代中复制整个数组只是为了添加一个项目-随着项目的增加,惩罚会变得更明显):如果您不知道需要多少元素,通常最好使用
集合
边走边添加
项。如果您确实知道需要多少元素,请在声明站点显式调整数组的大小:

Dim site_dates(1 To 10)
请注意,
Dim
语句是不可执行的,因此不能使用变量。使用
ReDim
语句执行以下操作:

ReDim site_dates(1 To datesCount)
ReDim
充当声明性语句,因此即使指定了
选项Explicit
,您也不需要先前的
Dim


在这种情况下,您可以使用
Application.WorksheetFunction.CountIf
获取与条件匹配的日期数,并在开始迭代值之前调整数组的大小。

首先检查是否使用了选项base 1,因为循环开始时使用1

如果您有一个从数据日期知道最大可能站点日期的设置,则可以在开始(循环之前)重新定义站点日期,使其与数据日期具有相同的边界

跟踪写入“If逻辑”循环计数器中的符合条件的项目数。 然后在最后,您可以重拨保留到生成的金额:

ReDim保存站点\u日期(1到qualifyingCounter)

备选地,不用担心性能,你可以认为对我来说是最容易的:

引用mscorlib并使用ArrayList

Dim data_dates
data_dates = Array("6/24/2019", "7/1/2019", "7/8/2019", "7/15/2019", "7/22/2019", "7/29/2019", "8/5/2019", "8/12/2019", "8/19/2019", "8/26/2019", "9/2/2019")

Dim siteDate_ArrayList As New ArrayList

Dim date_iter As Long
For date_iter = 0 To UBound(data_dates)
    If date_iter Mod 2 = 0 Then 'I changed this logic just for my test
        siteDate_ArrayList.Add data_dates(date_iter)
    End If
Next date_iter

Dim site_dates As Variant
'Please note that array resultant from ToArray on an empty ArrayList will have a Ubound of -1
site_dates = siteDate_ArrayList.ToArray
编辑: 要引用,请转到工具-->引用并按字母顺序查找mscorlib.dll。然后检查一下


“MSDN上的”有一节介绍动态阵列您是否使用选项base 1?否则您的循环将丢失第一个元素*uBond在空数组上抛出错误是否正常?*
site\u dates
不是空数组;这是一个未初始化的变量(空变量),所以是的,错误是正常的。啊,谢谢,我做了
Dim site_dates()作为数组
,但它不起作用。至于调整数组的大小,对于
site\u dates
,我不知道大小,因此必须动态调整它的大小。幸运的是,它永远不会有超过11个元素,所以我不太担心性能。如何引用mscorlib?我尝试将
Set clr=New mscoree.CorRuntimeHost
添加到脚本顶部和其他地方,但没有成功。在网上找不到任何显示其设置位置的示例
Dim data_dates
data_dates = Array("6/24/2019", "7/1/2019", "7/8/2019", "7/15/2019", "7/22/2019", "7/29/2019", "8/5/2019", "8/12/2019", "8/19/2019", "8/26/2019", "9/2/2019")

Dim siteDate_ArrayList As New ArrayList

Dim date_iter As Long
For date_iter = 0 To UBound(data_dates)
    If date_iter Mod 2 = 0 Then 'I changed this logic just for my test
        siteDate_ArrayList.Add data_dates(date_iter)
    End If
Next date_iter

Dim site_dates As Variant
'Please note that array resultant from ToArray on an empty ArrayList will have a Ubound of -1
site_dates = siteDate_ArrayList.ToArray