Excel VBA - 分配数组会更改LBound和UBound

时间:2013-10-20 21:33:42

标签: arrays excel vba bounds

我在Excel中有一些非常大的数据集需要解析 - 在数组中执行它比循环遍历工作表中的数据更快。将所有数据加载到数组中会导致内存问题(数据集很大),因此我计划将数据的子集加载到数组中,处理该数据,然后加载另一个子集。我希望使用定义LBound和UBound的数组“功能”来帮助我跟踪我在工作表中的位置。但我发现将工作表值分配给数组会更改边界。 以下代码演示了问题...

    Sub myTest3()
    Dim myRange As Range
    Dim myArray As Variant
    Dim myOffset As Long

        myOffset = 10
        Set myRange = Worksheets("RawData").Range("A1").CurrentRegion
        ReDim myArray(myOffset To myRange.Rows.Count, myRange.Columns.Count)
        MsgBox LBound(myArray, 1) & " to " & UBound(myArray)

        Set myRange = myRange.Offset(myOffset, 0).Resize(myRange.Rows.Count - myOffset, myRange.Columns.Count)

        myArray = myRange.Value2

        MsgBox LBound(myArray, 1) & " to " & UBound(myArray)

    End Sub

第一个MsgBox给了我“10到10931”。 第二个MsgBox给了我“1到10921”。

关于维护数组边界的任何想法都是我最初定义它们的吗?我知道在工作表中循环以使赋值可以做到,但它会很慢。

提前致谢。

1 个答案:

答案 0 :(得分:4)

在这种情况下,Excel VBA无法以您希望的方式运行。执行myArray = myRange.Value2时,myArray的原始内容已被替换。 Redim med数组被丢弃了。 Excel / VBA不会查看目标,它会替换它,或者更准确地说,它会创建一个新数组并使myaArray变量指向该目标。

因此,您需要更多代码才能获得您想要的目标。我会考虑把代码放到一个单独的函数中,然后在那里进行簿记:

Function ChunkAtOffset(rng As Range, rowsInChunk As Long, colsInChunk As Long, offsetRows As Long) As Variant
' Note: doesn't cater for the case where there are fewer than 'offsetRows' in the target    
Dim arr As Variant, result As Variant
Dim r As Long, c As Long

    arr = rng.offset(offsetRows).Resize(rowsInChunk, colsInChunk).Value2

    ReDim result(offsetRows To offsetRows + rowsInChunk - 1, 1 To colsInChunk)

    For r = 1 To rowsInChunk
        For c = 1 To colsInChunk
            result(offsetRows - 1 + r, c) = arr(r, c)
        Next
    Next

    ChunkAtOffset = result

End Function

如果我这样做:

Sub myTest4()

    Dim curReg As Range, ary As Variant, offset As Long
    With Range("A1")
        Set curReg = .CurrentRegion
        Do
            ary = ChunkAtOffset(.CurrentRegion, 10, .CurrentRegion.Columns.Count, offset)
            Debug.Print LBound(ary, 1) & " to " & UBound(ary)
            offset = offset + 10
        Loop Until offset >= .CurrentRegion.Rows.Count
    End With

End Sub

......我现在明白了:

0 to 9
10 to 19
20 to 29