在For ... Next循环中创建动态大小的数组

时间:2014-09-12 02:11:09

标签: arrays vba excel-vba for-loop excel

我有价格数据,有多个,但每天记录的价格可变。在单独的表格中,我有一个所有单独日期的列向量。我每天都需要一个当天所有价格的行向量。

我认为最好的方法是,每天都要复制价格并将它们放在一个数组中,我可以在另一张纸上粘贴转置。为此,我创建了两个循环,但我不知道如何存储每天的价格,并在我循环时为每一天填充这个动态大小的数组。我想我必须在每个循环中重新编写数组,但是当我循环遍历时如何填充数组的每个元素?

这是我所在位置的副本。

Sub GroupDayData()

    Dim RowCount As Integer
    Dim RowCount2 As Integer
    Dim r As Integer
    Dim j As Integer
    Dim Day As Date
    Dim No1 As Worksheet
    Dim No2 As Worksheet
    Dim TradePrice() As Double

    No1 = Worksheets("Sheet1")
    No2 = Worksheets("Sheet4")

    RowCount = Application.CountA(No1.Range("A:A"))
    RowCount2 = Application.CountA(No2.Range("A:A"))

    Application.ScreenUpdating = False

    'First I want to set the particular day I am looking at
    For r = 1 To RowCount2 + 1
    Day = Range("A" & r)
        'I then want to look at all values on that day
        For j = 1 To RowCount + 1
            If No1.Range("A" & j) = Day Then
            'This is where I am stuck. I want the code to populate an array as it runs through
            'this second loop, which I will paste and transpose in Sheet4, and then do the whole
            'thing again for the next day, therefore the size of the array is not constant.

    Application.ScreenUpdating = True

End Sub

在评论之后,我编辑了代码,但是我仍然没有在Sheet 2(No2)中显示任何输出。这个问题似乎有效地填充了数组,并将其粘贴到所选范围内。

Sub DayData()

    Dim RowCount As Integer
    Dim ClmnCount As Integer
    Dim r As Integer
    Dim j As Integer
    Dim No1 As Worksheet
    Dim No2 As Worksheet
    Dim Day As Date
    Dim Price() As Variant
    'Does this need to be declared as Double?
    Dim e As Integer

    Set No1 = Worksheets("Sheet1")
    Set No2 = Worksheets("Sheet2")

    RowCount = No1.Application.CountA(No1.Range("A:A")) + 1
    ClmnCount = No2.Cells(1, Columns.Count).End(xlToLeft).Column

    Application.ScreenUpdating = False

    For r = 1 To ClmnCount
        Day = No2.Cells(1, r)

        For j = 1 To RowCount
            If No1.Range("A" & j).Offset(1, 0) = Day Then
            'This loop will look through all date values and count the number that are the same
            e = e + 1
            'First I need to count how many elements are in the particular array
            ReDim Preserve Price(e)
            'Redim the array with its size
            'Is there a more efficient way rather than using redim each loop
            Price(e) = Range("B" & j).Offset(1, 0).Value
            'I think the problem is here
            End If
        Next j

        No2.Range(Cells(2, r), Cells(e + 1, r)) = Price
        Erase TradePrice

    Next r

    Application.ScreenUpdating = False

End Sub

3 个答案:

答案 0 :(得分:0)

在VBA中,您可以动态调整数组的大小

Redim Preserve TradePrice(newSize)

TradePrice(LastElement) = theNewValue

答案 1 :(得分:0)

有三种可能的方法。根据具体情况,我使用选项1或2.我几乎从不使用3.

1。提前计算

循环一次以计算数组需要包含多少元素。他们相应地Dim数组。然后循环第二次以填充数组。

优点:不必猜测数组大小。立即获取元素数,无论如何您可能需要其他地方。

缺点:循环两次=小的性能影响。略微不那么可读。

2。做好最坏的准备

Dim数组,以便它可以容纳最大可能数量的元素(在您的情况下,这可能是(RowCount2 + 1) * (RowCount + 1))。然后循环填充它,跟踪写入多少元素。最后,使用Redim Preserve将其修剪为精确数量的元素。

Pro :只循环一次;最佳表现。

Con :数组太大而无法启动;只有内存问题才会出现问题。

3。随着时间的推移补充

循环填充数组,每次向其添加元素时,使用Redim Preserve调整数组大小。

Pro :可以说是最具可读性的。

Con :反复调用Redim Preserve会严重降低速度,因为VBA不得不寻找新的RAM空间。这就是为什么我从来没有这样做过。

答案 2 :(得分:0)

我遵循了Jean-Francois Corbett的第一种方法,并提出了以下解决方案:

选项明确

选项基础1

Sub DayData()

Dim RowCount As Integer
Dim ClmnCount As Integer
Dim r As Integer
Dim j As Integer
Dim No1 As Worksheet
Dim No2 As Worksheet
Dim Day As Date
Dim Price() As Double
'Difference between a variant as array and an array of variants
Dim e As Integer

Set No1 = Worksheets("Sheet1")
Set No2 = Worksheets("Sheet2")

RowCount = No1.Application.CountA(No1.Range("A:A"))
ClmnCount = No2.Cells(1, Columns.Count).End(xlToLeft).Column

Application.ScreenUpdating = False

For r = 1 To ClmnCount
    Day = No2.Cells(1, r)
    e = 0

    For j = 1 To RowCount
        If No1.Range("A" & j).Offset(1, 0) = Day Then
        'This loop will look through all date values and count the number that are the same
        e = e + 1
        'First I need to count how many elements are in the particular array
        ReDim Preserve Price(e)
        'Redim the array with its size
        Price(e) = No1.Range("B" & j).Offset(1, 0).Value
        End If
    Next j

    e = e + 1
    No2.Range(Cells(2, r), Cells(e, r)).Value = Application.Transpose(TradePrice)
    'This is where I went wrong, first I needed to transpose my array, and second,
    'given I was starting from row 2, I need to add 1 to e, as well as include
    'Option Base 1

    Erase Price

Next r

Application.ScreenUpdating = False

End Sub