You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VBA匹配两工作表不同行索引行时差异行不显示到Sheet4求助

代码存在的问题
  • 读取Sheet1、Sheet2数据范围的逻辑不合理:你用H列的最后一行作为整表的截止行,一旦H列存在空值、或者其他列行数比H列多,会导致读入的a、b数组不完整,漏处理尾部行,这也是你只有首行匹配时输出才正常的核心原因。
  • 差异行覆盖不全:当前逻辑仅将「Sheet1中匹配到key但H列不等」的行写入Sheet4,完全遗漏了「Sheet2中存在但Sheet1中找不到对应key」的行,这部分也属于差异数据。
  • 字典覆盖问题:如果Sheet2存在多组C/D/E/I列完全相同的重复行,字典只会保留最后一行的索引,前面的重复行不会参与匹配。
  • 差异数组容量不足:你初始化d数组时仅按Sheet1的行数定义,如果Sheet2行数多于Sheet1,要写入Sheet2独有行时会出现下标越界。
  • 写入目标表时未清空旧数据:多次运行代码会在Sheet3、Sheet4原有数据后追加新内容,不会覆盖旧结果,容易混淆。
修复后代码
Sub MatchRows()
    Dim a As Variant, b As Variant, c As Variant, d As Variant
    Dim i As Long, j As Long, k As Long, m As Long, n As Long
    Dim dic As Object, ky As String
    Dim maxRow1 As Long, maxRow2 As Long, colCnt As Long
    Dim matchFlag As Variant ' 标记Sheet2的行是否被匹配过
    
    Set dic = CreateObject("Scripting.Dictionary")
    ' 修正取数范围逻辑:用UsedRange确定有效行,避免单列取行导致的漏读
    With Sheets("Sheet1")
        maxRow1 = .UsedRange.Rows(.UsedRange.Rows.Count).Row
        If maxRow1 < 2 Then Exit Sub ' 无有效数据直接退出
        a = .Range("A2:I" & maxRow1).Value
    End With
    With Sheets("Sheet2")
        maxRow2 = .UsedRange.Rows(.UsedRange.Rows.Count).Row
        If maxRow2 < 2 Then Exit Sub
        b = .Range("A2:I" & maxRow2).Value
    End With
    colCnt = UBound(a, 2)
    ' 初始化数组容量按两个表的最大行数,避免越界
    ReDim c(1 To UBound(a, 1) + UBound(b, 1), 1 To colCnt)
    ReDim d(1 To UBound(a, 1) + UBound(b, 1), 1 To colCnt)
    ReDim matchFlag(1 To UBound(b, 1)) ' 初始化匹配标记为False
    
    ' 字典存key对应的Sheet2行号列表,解决重复key问题
    For i = 1 To UBound(b, 1)
        ky = b(i, 3) & "|" & b(i, 4) & "|" & b(i, 5) & "|" & b(i, 9)
        If Not dic.exists(ky) Then
            Set dic(ky) = CreateObject("System.Collections.ArrayList")
        End If
        dic(ky).Add i
    Next

    ' 先处理Sheet1的所有行
    For i = 1 To UBound(a, 1)
        ky = a(i, 3) & "|" & a(i, 4) & "|" & a(i, 5) & "|" & a(i, 9)
        If dic.exists(ky) Then
            ' 遍历相同key的所有Sheet2行,找到未匹配的
            For Each j In dic(ky)
                If matchFlag(j) = False Then
                    matchFlag(j) = True ' 标记为已匹配
                    If a(i, 8) = b(j, 8) Then
                        ' 匹配成功写入Sheet3数组
                        k = k + 1
                        For n = 1 To colCnt
                            c(k, n) = a(i, n)
                        Next
                        c(k, 8) = 0
                    Else
                        ' H列不等写入差异数组
                        m = m + 1
                        For n = 1 To colCnt
                            d(m, n) = a(i, n)
                        Next
                        d(m, 8) = a(i, 8) - b(j, 8)
                    End If
                    Exit For
                End If
            Next
        Else
            ' Sheet1独有行写入差异
            m = m + 1
            For n = 1 To colCnt
                d(m, n) = a(i, n)
            Next
            d(m, 8) = "Sheet1独有"
        End If
    Next
    
    ' 处理Sheet2中未被匹配的独有行
    For j = 1 To UBound(b, 1)
        If matchFlag(j) = False Then
            m = m + 1
            For n = 1 To colCnt
                d(m, n) = b(j, n)
            Next
            d(m, 8) = "Sheet2独有"
        End If
    Next

    ' 写入前清空目标表旧数据,从第二行开始写(保留表头)
    Sheets("Sheet3").Range("A2:I" & Sheets("Sheet3").Rows.Count).ClearContents
    Sheets("Sheet4").Range("A2:I" & Sheets("Sheet4").Rows.Count).ClearContents
    If k > 0 Then Sheets("Sheet3").Range("A2").Resize(k, colCnt).Value = c
    If m > 0 Then Sheets("Sheet4").Range("A2").Resize(m, colCnt).Value = d

    Set dic = Nothing
End Sub
修复说明
  • 调整了数据源读取逻辑,用工作表已用范围确定截止行,不会因为某列有空值漏读数据
  • 补充了Sheet2独有行的判断,所有差异行都会写入Sheet4
  • 用ArrayList存储相同key的所有Sheet2行索引,解决重复key的覆盖问题
  • 扩大了数组初始化容量,避免下标越界
  • 写入前自动清空目标表旧数据,避免多次运行结果混淆

内容的提问来源于stack exchange,提问作者user14345147

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 06:24:03