【问题标题】:Excel vba, compare rows of two workbooks and replaceExcel vba,比较两个工作簿的行并替换
【发布时间】:2012-08-01 06:30:29
【问题描述】:

这里有一些关于我正在努力实现的背景。

我有一个 excel 文件,其中包含 10 张工作表,每张工作表都包含许多行数据。此工作簿发送给不同的人,每个人填写各自的信息,仅在 A、B 列中。我制作了一个 vba 脚本,它循环遍历所有填写的工作簿,并检查哪些行的单元格 AxBx 已填充。然后它将它们复制到一个新的工作簿中。

所以我现在拥有的是:

  1. 仅包含已填充 A、B 列的行的工作簿。
  2. 包含所有未填充行的工作簿。 (第一个)

我现在要做的是逐行检查,然后找到例如工作簿 A 的 sheet1 的第 1 行,减去工作簿 B 工作表 1 中的 A、B 列。找到该行后,我需要替换工作簿的 B 工作簿 A 中的行。

所以最后我会留下一个主工作簿(以前的工作簿 B),其中包含已填充和未填充的行。

我希望我没有把它弄得太复杂。任何有关实现此目标的最佳方法的见解将不胜感激。

【问题讨论】:

  • Any insight on what is the best way to achieve this would be appreciated. 你认为最好的方法是什么?您一定已经考虑过了 :) 您是否尝试过任何代码?向我们展示您尝试过的代码,在此基础上我们可以告诉您这是否是最好的方法,或者是否可以改进;)
  • 嗯,我想到的方法是我能想到的最简单的方法。遍历第一个工作簿的行,在第二个工作簿中找到它们中的每一个并替换它们。话虽如此,我不知道如何比较范围。 workbook1.sheet1.range("C1:F1") = orkbook2.sheet1.range("C1:F1") ?然后替换整行。我还没有创建任何代码,因为我不确定这是最好的方法。有很多行数据,这样可能有点矫枉过正。
  • 是的循环将是一个过度杀伤力。您可能想使用.FIND 看看这是否能让您入门。 siddharthrout.wordpress.com/2011/07/14/…
  • 这看起来会很好用。谢谢。一旦我取得了一些进展,我就会回来:)
  • 好吧,我可以给 .find 一个要查找的范围对象,但结果不正确。是否有关于如何使用 .find 查找范围的指南?据我了解,虽然我首先需要将范围转换为数组并逐个检查单元格。如果真的是这样,那就有点违背了目的,不是吗?

标签: vba excel compare rows


【解决方案1】:

就像我在我的 cmets 中提到的,可以使用 .Find 来实现您想要实现的目标。下面的代码示例打开工作簿AB。然后,它遍历 Workbook A 中 Col C 的值,并尝试在 Workbook B 的 Col C 中查找该值的出现。如果找到匹配项,则会比较该行中的所有列。如果所有列都匹配,则它会根据工作簿A 中的值写入工作簿B 的Col A 和Col B。找到匹配后,它会使用 .FindNext 在 Col C 中进行进一步匹配。

要对此进行测试,请将您提供给我的文件分别保存为 C:\A.xlsC:\B.xls。现在打开一个新工作簿并在一个模块中粘贴此代码。代码将工作簿ASheet7 与工作簿BSheet7 进行比较

我相信您现在可以修改其余表格的内容

尝试和测试(见帖子末尾的快照)

Sub Sample()
    Dim wb1 As Workbook, wb2 As Workbook
    Dim ws1 As Worksheet, ws2 As Worksheet
    Dim ws1LRow As Long, ws2LRow As Long
    Dim i As Long, j As Long
    Dim ws1LCol As Long, ws2LCol As Long
    Dim aCell As Range, bCell As Range
    Dim SearchString As String
    Dim ExitLoop As Boolean, matchFound As Boolean

    '~~> Open File 1
    Set wb1 = Workbooks.Open("C:\A.xls")
    Set ws1 = wb1.Sheets("sheet7")
    '~~> Get the last Row and Last Column
    With ws1
        ws1LRow = .Range("C" & .Rows.Count).End(xlUp).Row
        ws1LCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
    End With

    '~~> Open File 2
    Set wb2 = Workbooks.Open("C:\B.xls")
    Set ws2 = wb2.Sheets("sheet7")
    '~~> Get the last Row and Last Column
    With ws2
        ws2LRow = .Range("C" & .Rows.Count).End(xlUp).Row
        ws2LCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
    End With

    '~~> Loop Through Cells of Col C in workbook A and try and find it
    '~~> in Col C of workbook 2
    For i = 2 To ws1LRow
        SearchString = ws1.Range("C" & i).Value

        Set aCell = ws2.Columns(3).Find(What:=SearchString, LookIn:=xlValues, _
                    LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
                    MatchCase:=False, SearchFormat:=False)

        ExitLoop = False

        '~~> If match found
        If Not aCell Is Nothing Then
            Set bCell = aCell

            matchFound = True

            '~~> Then compare all columns
            For j = 4 To ws1LCol
                If ws1.Cells(i, j).Value <> ws2.Cells(aCell.Row, j).Value Then
                    matchFound = False
                    Exit For
                End If
            Next

            '~~> If all columns matched then wrtie to Col A/B
            If matchFound = True Then
                ws2.Cells(aCell.Row, 1).Value = ws1.Cells(i, 1).Value
                ws2.Cells(aCell.Row, 2).Value = ws1.Cells(i, 2).Value
            End If

            '~~> Find Next Match
            Do While ExitLoop = False
                Set aCell = ws2.Columns(3).FindNext(After:=aCell)

                '~~> If match found
                If Not aCell Is Nothing Then
                    If aCell.Address = bCell.Address Then Exit Do

                    matchFound = True

                    '~~> Then compare all columns
                    For j = 4 To ws1LCol
                        If ws1.Cells(i, j).Value <> ws2.Cells(aCell.Row, j).Value Then
                            matchFound = False
                            Exit For
                        End If
                    Next

                    '~~> If all columns matched then wrtie to Col A/B
                    If matchFound = True Then
                        ws2.Cells(aCell.Row, 1).Value = ws1.Cells(i, 1).Value
                        ws2.Cells(aCell.Row, 2).Value = ws1.Cells(i, 2).Value
                    End If
                Else
                    ExitLoop = True
                End If
            Loop
        End If
    Next
End Sub

快照

之前

之后

【讨论】:

  • 令人印象深刻!它确实有效,谢谢悉达多。我要研究你的代码,非常有用的东西,对于像我这样的新手来说很容易理解。
  • 嗯,我尝试在我的工作簿的真实 sheet7 上使用它,但它抛出运行时错误 424 - 需要对象,在线 If ws1.Cells(i, j).Value ws12.Cells( aCell.Row, j).Value 然后。我会调查的。
  • 抱歉打错了。将ws12 更改为ws2
  • 大声笑我应该注意到了,对不起。它工作得很好:D 现在我离目标只有一个 foreach 表循环:) 再次感谢!
  • 也许您应该考虑支持解决方案?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-09
相关资源
最近更新 更多