gpt4 book ai didi

arrays - 组合 2D(二维)数组

转载 作者:行者123 更新时间:2023-12-01 21:57:06 37 4
gpt4 key购买 nike

我正在 Excel 中使用 VBA 来使用 XML 文件并将特定信息转储到各个选项卡中。我希望能够组合二维数组。这些数组具有“已知”数量的列,但具有“未知”数量的行。考虑以下两个数组:

数组1:

a    b    c
d e f

数组2:

1    2    3
4 5 6

如果我想要以下结果,如何将它们组合到数组中:

数组3:

a    b    c
d e f
1 2 3
4 5 6

出于好奇,如果我想添加到右侧而不是底部,我将如何编码,如下所示:

数组4:

a    b    c    1    2    3
d e f 4 5 6

我似乎无法在任何地方找到这个问题的答案。

请记住,我上面的示例相当小,但实际上,我尝试一次使用大约 100,000 行数据来执行此操作。如果重要的话,只有六列数据。

这里的目标是组装一个大数组,然后将其一次性写入 Excel 工作表,因为当我分段执行时,性能非常差。

如果可能,我更喜欢不需要迭代的解决方案。

我问这两种方式的原因是实际上我想按顺序添加。例如,假设我有四个数组,A、B、C、D。

首先添加数组A:

A

然后,添加数组B:

A    B

然后,添加数组C:

A    B
C

然后,添加数组D:

A    B
C D

等等...

请记住,上述每个数组的大小都将调整为正确“适合”,这意味着 A 和 B 具有相同的行数,但列数不同。另一方面,A 和 C 具有相同的列数但不同的行数。等等...

我想使用下面的 Macro Man 代码添加演示。以下是他提供的内容(我添加了一些内容,以便读者可以复制/粘贴):

Option Explicit

Sub Testing()

Dim Array1(0 To 1, 0 To 2) As String
Array1(0, 0) = "a"
Array1(0, 1) = "b"
Array1(0, 2) = "c"
Array1(1, 0) = "d"
Array1(1, 1) = "e"
Array1(1, 2) = "f"

Dim Array2(0 To 1, 0 To 2) As String
Array2(0, 0) = "1"
Array2(0, 1) = "2"
Array2(0, 2) = "3"
Array2(1, 0) = "4"
Array2(1, 1) = "5"
Array2(1, 2) = "6"

Dim i As Long
For i = 1 To 25000

With Range("A" & Rows.Count).End(xlUp).Offset(IIf(IsEmpty([A1]), 0, 1), 0)
.Resize(UBound(Array1, 1) - LBound(Array1, 1) + 1, _
UBound(Array1, 2) - LBound(Array1, 2) + 1).Value = Array1
End With

With Range("A" & Rows.Count).End(xlUp).Offset(IIf(IsEmpty([A1]), 0, 1), 0)
.Resize(UBound(Array2, 1) - LBound(Array2, 1) + 1, _
UBound(Array2, 2) - LBound(Array2, 2) + 1).Value = Array2
End With

Next i

End Sub

当您运行上述代码时,每次都会返回到电子表格以写入少量数据,这需要很长时间才能运行。在我的双 Xeon 机器上,大约 25-30 秒。

但是,如果您首先重写并填充数组,然后写入电子表格一次,则它会在大约一秒钟内运行。

Option Explicit

Sub Testing()

Dim Array1(0 To 99999, 0 To 2) As String
Array1(0, 0) = "a"
Array1(0, 1) = "b"
Array1(0, 2) = "c"
Array1(1, 0) = "d"
Array1(1, 1) = "e"
Array1(1, 2) = "f"

Dim i As Long
For i = 0 To 99999

Array1(i, 0) = "a"
Array1(i, 1) = "b"
Array1(i, 2) = "c"

Next i

With Range("A" & Rows.Count).End(xlUp).Offset(IIf(IsEmpty([A1]), 0, 1), 0)
.Resize(UBound(Array1, 1) - LBound(Array1, 1) + 1, _
UBound(Array1, 2) - LBound(Array1, 2) + 1).Value = Array1
End With

End Sub

我希望看到一个具有相同功能的解决方案,除了能够添加数据“ block ”而不是单个项目。理想情况下,将数组添加到更大的数组中。如果“父”数组能够以某种方式动态调整自身大小,那就更好了。

下面约翰·科尔曼的回答非常有效。

我实际上将 Macro Man 的一些内容与 John 的 test() 子例程结合起来,这动态地调整了范围的大小:

Option Explicit

Sub test()
Dim A As Variant, B As Variant
ReDim A(0 To 1, 0 To 1)
ReDim B(0 To 1, 0 To 1)
A(0, 0) = 1
A(0, 1) = 2
A(1, 0) = 3
A(1, 1) = 4
B(0, 0) = 5
B(0, 1) = 6
B(1, 0) = 7
B(1, 1) = 8

Dim Array1 As Variant
Array1 = Combine(A, B)

With Range("A" & Rows.Count).End(xlUp).Offset(IIf(IsEmpty([A1]), 0, 1), 0)
.Resize(UBound(Array1, 1) - LBound(Array1, 1) + 1, _
UBound(Array1, 2) - LBound(Array1, 2) + 1).Value = Array1
End With
End Sub

最佳答案

这是一个 VBA 函数,可以将两个二维数组合并为一个二维数组。它可以在 VBA 中使用,也可以直接在 Excel 中作为数组公式使用。在 VBA 中,迭代是不可避免的,因为该语言没有用于连接数组之类的原语:

Function Combine(A As Variant, B As Variant, Optional stacked As Boolean = True) As Variant
'assumes that A and B are 2-dimensional variant arrays
'if stacked is true then A is placed on top of B
'in this case the number of rows must be the same,
'otherwise they are placed side by side A|B
'in which case the number of columns are the same
'LBound can be anything but is assumed to be
'the same for A and B (in both dimensions)
'False is returned if a clash

Dim lb As Long, m_A As Long, n_A As Long
Dim m_B As Long, n_B As Long
Dim m As Long, n As Long
Dim i As Long, j As Long, k As Long
Dim C As Variant

If TypeName(A) = "Range" Then A = A.Value
If TypeName(B) = "Range" Then B = B.Value

lb = LBound(A, 1)
m_A = UBound(A, 1)
n_A = UBound(A, 2)
m_B = UBound(B, 1)
n_B = UBound(B, 2)

If stacked Then
m = m_A + m_B + 1 - lb
n = n_A
If n_B <> n Then
Combine = False
Exit Function
End If
Else
m = m_A
If m_B <> m Then
Combine = False
Exit Function
End If
n = n_A + n_B + 1 - lb
End If
ReDim C(lb To m, lb To n)
For i = lb To m
For j = lb To n
If stacked Then
If i <= m_A Then
C(i, j) = A(i, j)
Else
C(i, j) = B(lb + i - m_A - 1, j)
End If
Else
If j <= n_A Then
C(i, j) = A(i, j)
Else
C(i, j) = B(i, lb + j - n_A - 1)
End If
End If
Next j
Next i
Combine = C
End Function

我用 4 种不同的方式对其进行了测试。首先,我在电子表格中输入了两个示例数组,并直接在 Excel 中使用 Combine 作为数组公式:

enter image description here

这里A7:C10包含数组公式

{=combine(A1:C2,A4:C5)}

而A12:F13包含数组公式

{=combine(A1:C2,A4:C5,FALSE)}

然后,我运行了以下子命令:

Sub test()
Dim A As Variant, B As Variant
ReDim A(0 To 1, 0 To 1)
ReDim B(0 To 1, 0 To 1)
A(0, 0) = 1
A(0, 1) = 2
A(1, 0) = 3
A(1, 1) = 4
B(0, 0) = 5
B(0, 1) = 6
B(1, 0) = 7
B(1, 1) = 8
Range("A15:B18").Value = Combine(A, B)
Range("C15:F16").Value = Combine(A, B, False)
End Sub

输出:

enter image description here

关于arrays - 组合 2D(二维)数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32979838/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com