我正在比较 VBA for Excel 2010 中的两个数组。这是我的示例代码:
Dim vArray1 As Variant
Dim vArray2 As Variant
Set wb1 = ActiveWorkbook
Set myTable = wb1.Worksheets(3).ListObjects("Table3")
vArray1 = myTable.DataBodyRange
vArray2 = wb1.Worksheets(2).Range("B1:B" & lRow1).Value
k = 1
For i = LBound(vArray1) To UBound(vArray1)
For j = LBound(vArray2) To UBound(vArray2)
If vArray1(i, 1) = vArray2(j, 1) Then
' Do nothing
Else
vArray3(k, 1) = vArray1(i, 1)
k = k + 1
End If
Next
Next
我想将表 3 中的第 1 列与 vArray2 中存储的范围进行比较。
任何存在于 vArray1 但不存在于 vArray2 中的值都需要存储在 vArray3 中。不幸的是,我无法完成这件事。任何帮助将不胜感激。
Edit1:我稍微重写了你的循环,这就是我认为问题的原因。如果未提供,则 Ubound 和 Lbound 假定为第一个维度。因此,您执行以下操作的方式应该返回正确的上限和下限。但当然,在处理二维数组时最好是明确的。另外 vArray3 应该是 Dimensioned。我在你的代码中没有看到它。还添加了一个 Boolean 变量。
ReDim vArray3 (1 to 10, 1 to 2) '~~> change to suit
Dim dup As Boolean: k = 1
For i = LBound(vArray1, 1) To UBound(vArray1, 1) '~~> specify dimension
dup = False
For j = LBound(vArray2, 1) To UBound(vArray2, 1) '~~> specify dimension
If vArray1(i, 1) = vArray2(j, 1) Then
dup = True: Exit For
End If
Next j
If Not dup Then '~~> transfer if not duplicate
vArray3(k, 1) = vArray1(i, 1)
k = k + 1
End If
Next I
或者你可以使用这样的匹配:
'~~> Use 1D array instead by using Transpose
vArray2 = Application.Transpose(wb1.Worksheets(2).Range("B1:B" & lRow1))
For i = LBound(vArray1, 1) To UBound(vArray1, 1) '~~> specify dimension
If IsError(Application.Match(vArray1(i, 1), vArray2, 0)) Then
vArray3(k, 1) = vArray1(i, 1)
k = k + 1
End If
Next i
此代码检查两个数组 varArray1 和 varArray2 之间的相等性。 Join 函数用于将每个数组的元素连接成一个以逗号分隔的字符串。
然后,使用“=”运算符比较两个结果字符串,以检查它们是否相同。
如果相等,则变量 IsEqual 设置为 True,表示数组相等。如果它们不相等,则代码不会修改 IsEqual 的值,因此它仍然为 False(或之前的任何值)。
If (Join(varArray1, ",") = Join(varArray2, ",")) Then
IsEqual = True
End If
我也在比较 2 个数组的算法上遇到了困难。我从这里的讨论中借用了一些想法。最终,我开发了自己的算法。我想与社区分享。我在算法正文中做了一些注释。此外,我还提供了扩展的解释。我希望有人会发现我的思维方式有帮助。
Sub Comparing_2_Arrays()
Dim arrayOSV6001() As Variant
Dim arrayPayTerms() As Variant
Dim arrayContracts() As Variant
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim l As Integer
Dim intRowsOSV6001 As Integer
Dim intRowsPayTerms As Integer
Dim m As Variant
Dim n As Variant
' Comment line 0:
l = 1
k = 1
' Comment line 1
ReDim arrayOSV6001(1 To intRowsOSV6001)
ReDim arrayPayTerms(1 To intRowsPayTerms)
ReDim arrayContracts(1 To 1)
' Comment line 2
For i = 1 To UBound(arrayOSV6001)
' Comment line 3
For j = 1 To UBound(arrayPayTerms)
m = arrayOSV6001(i, 1)
n = arrayPayTerms(j, 1)
' Comment line 4
If m <> n Then
k = k + 1
Else
k = k + 0
End If
Next j
' Comment line 5
If k = j Then
arrayContracts(l) = m
' Comment line 6
k = 1
l = l + 1
ReDim Preserve arrayContracts(1 To l)
Else
k = 1
End If
Next i
' Comment line 7
If l = 1 Then
MsgBox "Missing and unique elements haven't been found."
Exit Sub
Else
' Comment line 8
l = l - 1
ReDim Preserve arrayContracts(1 To l)
End If
End Sub
变量定义
arrayOSV6001 - 总账中的合约数组
arrayPayTerms - 付款条款寄存器中的合同数组
arrayContracts - arrayPayTerms 中缺少唯一合约的数组,但存在于 arrayOSV6001 中
i - arrayOSV6001
数组元素的计数器变量
j - arrayPayTerms 数组元素的计数器变量
k - arrayPayTerms 不等于 arrayOSV6001
元素数量的计数器变量
l - 用于确定 arrayContracts
维度的变量
intRowsOSV6001 - 用于确定 arrayOSV6001
维度的变量
intRowsPayTerms - 用于确定 arrayPayTerms 维度的变量
m - arrayOSV6001
元素值的变量
n - arrayPayTerms
评论行
注释行0:定义变量的初始值:l和k
注释行1:定义数组的初始维度:arrayOSV6001、arrayPayTerms、arrayContracts。 intRowsOSV6001 等于从总账下载的合约数量。 intRowsPayTerms 等于从付款条件寄存器下载的合约数量。
注释行2:启动循环检查arrayOSV6001的元素值
注释行 3: 启动循环以检查 arrayPayTerms 元素的值
注释行 4: 成对比较 arrayOSV6001 和 arrayPayTerms 的值,如果值不相似,则将 K 计数器加一。
注释行5:如果arrayPayTerms中不等于arrayOSV6001元素的元素数量等于J循环中的迭代次数,则意味着已经找到arrayOSV6001的唯一元素。然后将找到的唯一元素记录在 arrayContracts 中。
注释行 6: 将 K 计数器减少到 0,并将下一个唯一元素的 arrayContracts 维度增加 1。
注释行 7: 如果 L 和 J 循环结束后 arrayContracts 的维数没有改变,则意味着尚未找到 arrayPayTerms 中缺失且存在于 arrayOSV6001 中的唯一元素。然后退出子程序。
注释行 8: 如果在 L 和 J 循环完成后 arrayContracts 的维度发生了变化,则重新调整 arrayContracts 的维度并从为 arrayOSV6001 的下一个唯一元素创建的 arrayContracts 中消除最后一个空元素