excel - 比较两张工作表并仅使用唯一 ID 突出显示不匹配的行
问题描述
我想匹配来自两个不同工作表的行并仅在不匹配行的第一列中突出显示,或者更好地将不匹配的行复制到新工作表中。代码应比较两个工作表的行并为第二个工作表中的新行着色。Sheet2(比如 2020 年 1 月)比 Sheet1(2019 年 12 月)包含更多的行,因为它是最近更新的工作表,它们都包含超过 22k 的行,并且都具有唯一 ID 作为第一列。
我下面的代码试图突出显示所有不匹配的单元格,并且需要更长的时间才能完成。我希望代码只为 A 列(vb.Red)中不匹配的部分着色(因为它是唯一 ID),同时忽略其余列/单元格(vb.Yellow),或者如果可能,复制突出显示的行到一个新的工作表中。
Sub RunCompare()
Call compareSheets("Sheet1", "Sheet2") 'compareSheets("2019-01 Database", "2019-02 Database")
End Sub
Sub compareSheets(shtSheet1 As String, shtSheet2 As String)
Dim c As Integer, j As Integer, i As Integer, mydiffs As Integer, cnt1 As Integer, cnt2 As Integer
Dim noexist As Integer
cnt2 = Worksheets("Sheet2").Cells.SpecialCells(xlCellTypeLastCell).Row
cnt1 = Worksheets("Sheet1").Cells.SpecialCells(xlCellTypeLastCell).Row
'For each cell in sheet2 that is not the same in Sheet1, color it yellow
For i = 1 To cnt2
For j = 1 To cnt1
If ActiveWorkbook.Worksheets(shtSheet2).Cells(i, 1).Value = ActiveWorkbook.Worksheets(shtSheet1).Cells(j, 1).Value Then
For c = 2 To 22
If Not ActiveWorkbook.Worksheets(shtSheet2).Cells(i, c).Value = ActiveWorkbook.Worksheets(shtSheet1).Cells(j, c).Value Then
ActiveWorkbook.Worksheets(shtSheet2).Cells(i, c).Interior.Color = vbYellow
mydiffs = mydiffs + 1
End If
Next
Exit For
End If
If j = cnt1 Then
ActiveWorkbook.Worksheets(shtSheet2).Cells(i, 1).Interior.Color = vbRed
End If
Next
Next
'Display a message box to demonstrate the differences and if there is a new entry on the second sheet
'MsgBox mydiffs & ":differences found, " & noexist & ":no exist", vbInformation
ActiveWorkbook.Sheets(shtSheet2).Select
End Sub
解决方案
让我们简化任务并逐步完成。
- 两张表中的输入如下所示:
然后,我们可以考虑读取这些并将它们保存到一个数组中:
Set rangeA = ThisWorkbook.Worksheets(1).Range("A1:Z1")
Set rangeB = ThisWorkbook.Worksheets(2).Range("A1:ZZ1")
Dim arrayA As Variant
Dim arrayB As Variant
With Application
arrayA = .Transpose(.Transpose(rangeA))
arrayB = .Transpose(.Transpose(rangeB))
End With
- 在vba中,两个数组中的数据之间的循环非常快。仅当两个数组中的两个值匹配时才写入第三个工作表:
Dim myValA As Variant
Dim myValB As Variant
Dim currentRow As Long: currentRow = 1
For Each myValA In arrayA
For Each myValB In arrayB
If myValA = myValB Then
ThisWorkbook.Worksheets(3).Cells(currentRow, 1) = myValA
currentRow = currentRow + 1
End If
Next
Next
这是第三个工作表中的结果,所有匹配值都在一行中:
这是整个代码的样子:
Sub CompareTwoRanges()
Dim rangeA As Range
Dim rangeB As Range
Set rangeA = ThisWorkbook.Worksheets(1).Range("A1:Z1")
Set rangeB = ThisWorkbook.Worksheets(2).Range("A1:ZZ1")
Dim arrayA As Variant
Dim arrayB As Variant
With Application
arrayA = .Transpose(.Transpose(rangeA))
arrayB = .Transpose(.Transpose(rangeB))
End With
Dim myValA As Variant
Dim myValB As Variant
Dim currentRow As Long: currentRow = 1
For Each myValA In arrayA
For Each myValB In arrayB
If myValA = myValB Then
ThisWorkbook.Worksheets(3).Cells(currentRow, 1) = myValA
currentRow = currentRow + 1
End If
Next
Next
End Sub
注意- 如果将结果写入数组然后从数组写入工作表,则会有另一个性能奖励。因此,写入只会发生一次。这是数组声明之后需要在代码中实现的更改:
Dim myValA As Variant
Dim myValB As Variant
Dim resultArray() As Variant
ReDim Preserve resultArray(2 ^ 20)
Dim i As Long: i = 0
For Each myValA In arrayA
For Each myValB In arrayB
If myValA = myValB Then
resultArray(i) = myValA
i = i + 1
End If
Next
Next
ReDim Preserve resultArray(i)
ThisWorkbook.Worksheets(3).Cells(1, 1).Resize(UBound(resultArray)) = Application.Transpose(resultArray)
推荐阅读
- python-3.x - 表数据未在 python selenium 中检索
- javascript - UploadComplete 事件未在 plupload 中触发
- ios - IOS 在 Google SignIn React Native Expo 32 上崩溃
- javascript - 如何将 Google 表格脚本代码启动到 Google 应用脚本网络应用中?
- reactjs - 如何使用带有反应钩子的 redux 状态
- bash - 使用grep打印存储在循环变量中的重叠字符串的字符位置?
- amazon-s3 - 阻止管理员通过控制台访问 S3 存储桶
- c++ - 默认模板类 lambda
- java - 在准备好的语句中批量运行多个查询
- azure - AzureMapsCodeSamples 无法在本地驱动器中运行