最有效的方法是在大范围内解析到数组VBA

问题描述 投票:1回答:3

我在excel中有大量数据,我想将其解析为用户定义函数的数组。范围是2250 x 2250.通过for循环解析每个单元格需要太长时间,并且它太大而无法通过此方法分配给数组:

dim myArr as Variant
myArr = range("myrange")

只是在这里集思广益,解析每一列并加入数组会更有效吗?有任何想法吗?

谢谢

arrays excel vba excel-vba matrix
3个回答
4
投票

你快到了。

您需要的代码是:

Dim myArr as Variant
myArr = range("myrange").Value2

请注意,我正在使用范围的.Value2属性,而不仅仅是“值”,它会读取格式和区域设置,并且可能会破坏任何日期

另请注意,我没有打扰Redim并指定数组的维度:Value和Value2属性是一个二维数组,(1到Rowcount,1到Col Count)...除非它是一个单元格,这将是一个标量变体,它会破坏任何预期数组的下游代码。但这不是你已知的2250 x 2250范围的问题。

如果反转操作并将数组写回某个范围,则需要将接收范围的大小精确设置为数组的尺寸。同样,不是你问的问题的问题:但这两个操作通常是一起的。

一般原则是工作表的每次“点击”大约需要二十分之一秒 - 有些机器要快得多,但它们都有糟糕的日子 - 而“点击”或将单个单元格读取到变量几乎就是与将七百万个细胞范围读入变体阵列相同。两者都比一次读取一个单元格中的范围快几百万倍。

无论哪种方式,一旦你完成了“读入”并停止与工作表交互,你也可以将VBA中的任何操作统计为零时间。

这些数字都是非常粗略和准备好的,但是一般原则将持续到你开始分配不适合工作内存的阵列的那一刻,而且,这不是你今天的问题。

当你完成时,请记住Erase数组变体,而不是依赖它超出范围:这将产生差异,具有这个大小的范围。


2
投票

这很好用。

Sub T()
    Dim A() As Variant

    A = Range("A2").Resize(2250, 2250).Value2

    Dim i As Long, j As Long
    For i = 1 To 2250
        For j = 1 To 2250
            If i = j Then A(i, j) = 1
        Next j
    Next i

    Range("A2").Resize(2250, 2250).Value2 = A
End Sub

0
投票

我认为最好的选择是:

  1. 尝试将数据限制为合理的数字,例如每次1,000,000个值。
  2. 添加一些错误处理以捕获Out of Memory错误,然后再试一次,但将大小减半,然后减少三分之一,四分之一等......直到它工作。

无论哪种方式,如果我们使用大约5,000,000个值的数据集并且您想确保程序将运行,您将需要调整代码以切断数据。

© www.soinside.com 2019 - 2024. All rights reserved.