我在编写用于比较多张工作表(同一个 Excel 文件)中的多列的宏时遇到问题。我写的很少,但他们花了很长时间,以至于 excel 崩溃了。
假设我在同一个文件中有 4 张纸。Sheet1 有两列(B 和 C)和 7000 行。Sheet2 空工作表新条目。Sheet3 旧条目的空白表,但有一些更新的值/信息。Sheet4 是一个有 2 列(A 和 B)和 22000 行的数据库。
我需要将 Sheet1 中的 A 列与 Sheet4 中的 B 列进行比较。如果 A 列 sheet1 中有全新的条目,则将该条目从 A 列 sheet1(及其相应值从 B 列 sheet1)复制到 Sheet2 中的新行(A 列和 B 列)。如果 A 列 Sheet1 中的条目已经在 A 列 sheet4 中,则比较它们各自的 B 列值。如果 Sheet 1 中的 A 列 + B 列组合在 Sheet4 中,则忽略它。如果 A 列 Sheet1 中的值位于 A 列 Sheet4 中,但它们各自的 B 列值不匹配,则将 Sheet1 中的 A 列 + B 列复制到 Sheet3 中的新行(A 列和 B 列)。
我希望它足够清楚。由于行数(Sheet1 中的 7000 与 Sheet4 中的 20000 相比),我无法编写一个在一分钟内处理所有内容的宏。
有什么帮助吗?
编辑1:我使用了@FaneDuru 建议的代码(谢谢!)。但我遇到一个错误:“运行时错误'457':此键已与此集合的元素相关联”是因为我在同一列中有许多重复值吗?
编辑 2:似乎 VBA 无法识别“if not dict3.exists”代码。当我用小写字母键入“.exists”并跳转到另一行时,应该将其更正为大写“.Exists”,对吗?它没有这样做。
编辑3:我做了更多测试。我正在休息并运行代码。当我在这一行“If WorksheetFunction.CountIf(rngA4, arr1(i, 1)) > 0 Then”上放置中断时,不会发生错误。当我将中断放在“For j = UBound(arr4) To 1 Step -1”下面的一行时,错误正在发生。
错误是:“运行时错误'457':此键已与此集合的元素相关联”
Private Sub CommandButton1_Click()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
Application.DisplayAlerts = False
Dim arr1, arr2, arr3, arr4, dict2 As Object, dict3 As Object, rngA4 As Range
Dim rngB4 As Range, i As Long, j As Long, lastR1 As Long, lastR4 As Long
lastR1 = Sheet1.Range("A" & Sheet1.Rows.Count).End(xlUp).Row
lastR4 = Sheet4.Range("A" & Sheet4.Rows.Count).End(xlUp).Row
Set rngA4 = Sheet4.Range("A2:A" & lastR4)
Set rngB4 = Sheet4.Range("B2:B" & lastR4)
arr1 = Sheet1.Range("B2:C" & lastR1).Value
arr4 = Sheet4.Range("A2:B" & lastR4).Value
Set dict2 = CreateObject("Scripting.Dictionary")
Set dict3 = CreateObject("Scripting.Dictionary")
For i = UBound(arr1) To 1 Step -1
If WorksheetFunction.CountIf(rngB4, arr1(i, 1)) = 0 Then
dict2.Add arr1(i, 1), arr1(i, 2):
End If
If WorksheetFunction.CountIf(rngA4, arr1(i, 1)) > 0 Then
For j = UBound(arr4) To 1 Step -1
If arr1(i, 1) = arr4(j, 1) Then
If arr1(i, 2) <> arr4(j, 2) Then
If arr1(i, 2) <> arr4(j, 2) Then
dict3.Add arr1(i, 1), arr1(i, 2): Exit For
End If
End If
Next j
End If
Next i
If dict2.Count > 0 Then
arr2 = Application.Transpose(Array(dict2.keys, dict2.Items))
Sheet2.Range("A2").Resize(dict2.Count, 2).Value = arr2
End If
If dict3.Count > 0 Then
arr3 = Application.Transpose(Array(dict3.keys, dict3.Items))
Sheet3.Range("A2").Resize(dict3.Count, 2).Value = arr3
End If
MsgBox "Done!"
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.EnableEvents = True
Application.DisplayAlerts = True
End Sub