Arrays 剥离列或行以形成1D数组

Arrays 剥离列或行以形成1D数组,arrays,vba,excel,for-loop,Arrays,Vba,Excel,For Loop,我想从2D数组创建一个1D数组,而不使用一行代码循环,例如: newvec = oldvec(:,3) 在MATLAB中,它将从“oldvec”的第3列创建一个一维数组“newvec”。我的搜索告诉我在VBA中执行此操作的唯一方法是循环。例如: redim newvec(ubound(oldvec,1)) for i = 1 to ubound(oldvec,1) newvec(i) = oldvec(i,3) next i 是否有一个内置结构,用于剥离现有二维数组的全部奇异

我想从2D数组创建一个1D数组,而不使用一行代码循环,例如:

newvec = oldvec(:,3)
在MATLAB中,它将从“oldvec”的第3列创建一个一维数组“newvec”。我的搜索告诉我在VBA中执行此操作的唯一方法是循环。例如:

redim newvec(ubound(oldvec,1))
    for i = 1 to ubound(oldvec,1)
    newvec(i) = oldvec(i,3)
next i

是否有一个内置结构,用于剥离现有二维数组的全部奇异维度,以构建新的一维数组?

与大多数常见编程语言不同,VBA中没有用于此目的的内置函数。但是,使用索引函数有一个变通方法:

Application.Index(MultidimArray, Row_Number, Column_Number)
若要从源数组中提取列,应将“0”作为 行数参数。类似地,要从源数组中提取行, “0”应作为列号参数传递

因此,如果要从“oldvec”的第3列创建1D数组“newvec”:

你可以找到更多

编辑:


使用
For循环
比使用
索引函数
快得多。因此,您最好坚持使用
for loop
。有关详细信息,请参阅注释。

测试写入一个范围,然后返回

Tehscript的帖子是正确的

在我的测试中,For循环的
速度是
索引的五倍,比写入范围然后将第三列转储回1D数组快10倍

Sub Test()
Dim X
Dim Y
Dim lngCNt As Long
Dim dbTimer As Double
X = [a1:c1000000].Value2

dbTimer = Timer()
'test 1
'Y = Application.Index(X, 0, 3)


'test 2
'ReDim Y(1 To UBound(X))
'For lngCNt = 1 To UBound(Y)
    'Y(lngCNt) = X(lngCNt, 3)
'Next

'test 3
[d1:f1000000].Value2 = X
Y = Application.Transpose([f1:f1000000])

Debug.Print Timer() - dbTimer
End Sub

您可以将二维数组复制到一个
范围
,然后将该范围的第3列读取到一个1D数组中。但为了速度,我更喜欢留在VBA中,不管您的方法如何,都会生成一个二维数组,其中一个维度的值为1,因为VBA总是以二维数组的形式从Excel中读取数据。不太可能,阅读有关Application.TransposeThanks-Tehscript的信息。调用应用程序函数是否会明显降低VBA的速度,比如说在VBA中编写一个循环?因为在本例中,我处理的是相对较小的数据,我怀疑不是。我没有测试所有数据,但据我所知,内置函数的工作速度比循环快得多。为此,我记得测试了CountA函数(对某个范围内的非空白单元格进行计数)以防止在该范围内循环(通过检查单元格值)。内置函数的速度要快得多。如果可以的话,我也会看一看索引。我会把你们对速度的评论看得很好。再次感谢。我刚刚测试了两种方法。不幸的是,这次内置函数比for循环慢。我刚刚测试了
newvec=Application.Index(oldvec,0,3)
下一步I=1到1000000 newvec(I)=oldvec(I,3)所需的时间。为了得到平均时间,我对100万个值运行了10次<代码>索引函数
耗时14.56614秒(平均值为1.4566秒),循环
耗时2.027344秒(平均值为0.2027秒)。所以我建议你使用for-loop.Tehscript,你太棒了!那是真的,循环法则!
Sub Test()
Dim X
Dim Y
Dim lngCNt As Long
Dim dbTimer As Double
X = [a1:c1000000].Value2

dbTimer = Timer()
'test 1
'Y = Application.Index(X, 0, 3)


'test 2
'ReDim Y(1 To UBound(X))
'For lngCNt = 1 To UBound(Y)
    'Y(lngCNt) = X(lngCNt, 3)
'Next

'test 3
[d1:f1000000].Value2 = X
Y = Application.Transpose([f1:f1000000])

Debug.Print Timer() - dbTimer
End Sub