【问题标题】:VBA to compare two sheets and copy certain columns in the row if they are differentVBA比较两张纸并复制行中的某些列(如果它们不同)
【发布时间】:2017-12-20 18:08:49
【问题描述】:

我要做的是查看两张不同的表格来比较人们和他们的国民保险号码。

表 1 是来自一个系统的一组数据,表 2 是来自不同系统的另一组数据。我想要做的是首先比较两张表中的第 1 列,其中包含该人唯一的 id,一旦每张表中第 1 列中的条目相同,那么这就是同一个人。那么

然后我想要做的是比较存储在表 1 上第 1 列右侧的 17 列和表 2 上右侧 23 列的值(两者都是国家保险号码)。

只有当它们不同时,我才想复制表 1 中行的前 3 列(编号、名字和姓氏)以及两张表中的国民保险编号值(Sheet1(0,17)Sheet2(0, 23) 到 Sheet3。

这是我正在尝试的代码,它最初复制整行,如果逻辑有效,我可以更改为仅复制我想要的单元格,但无济于事,它似乎复制了几乎整个工作表 1.....

Sub compareData()
    Dim ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet
    Dim i As Long, j As Long
    Dim newSheetPos As Integer

    Set ws1 = ActiveWorkbook.Sheets("Sheet1")
    Set ws2 = ActiveWorkbook.Sheets("Sheet2")
    Set ws3 = ActiveWorkbook.Sheets("Sheet3")

    newSheetPos = ws3.Cells(ws3.Rows.Count, 2).End(xlUp).Row

    For i = 1 To ws1.Cells(ws1.Rows.Count, 2).End(xlUp).Row
        For j = 1 To ws2.Cells(ws2.Rows.Count, 2).End(xlUp).Row
            If ws1.Cells(i, 1).Value = ws2.Cells(j, 1).Value Then
                If ws1.Cells(i, 17).Value <> ws2.Cells(j, 23).Value Then
                    ws1.Cells(j, 1).EntireRow.Copy ws3.Cells(newSheetPos, 1)
                    newSheetPos = newSheetPos + 1
                Else
                End If
            Else
            End If
        Next j
    Next i
End Sub

【问题讨论】:

  • 您确定两张表都以相同的格式存储 NI 编号吗?这可能会导致 IF 语句始终为 false 并因此复制大多数行?
  • 是的,它们是相同的格式 2xUpperCase 6 个数字和 1 个大写字母,这就是我想要的。在两张纸上的第 1 列中找到匹配项,查看第 17 行第 1 行,第 2 行第 23 行。如果单元格不匹配,那么我想复制 sheet1 上不匹配行的前 3 列和国家保险两个都。 .它看起来像这样 Col1(ID), Col2(FirstName), Col3(Surname), Col4(NINO), Col5(NINO2) 前 4 列将来自 Sheet1,第 5 列来自 Sheet2
  • 那么这里还有其他东西在起作用,因为您的代码似乎没问题,您应该仔细检查所有比较的格式是否相同,我并不是指它们的方式显示在单元格上,但该单元格的格式,即。文本、常规、自定义...您能分享一些示例数据吗?我已经使用一些虚拟数据进行了简化测试,但它对我来说可以正常工作。
  • @Leighholling Edit 附加信息有问题。你能舒服地阅读你在评论中发布的内容吗?
  • 不,我不能,但我不能把它放到一个答案中来格式化它,它是删除的样本数据,如果我诚实的话,我什至可能会删除这个问题。不要以为可以回答

标签: vba excel


【解决方案1】:

遇到类似问题后,我发现使用Trim(), UCase().Value2 属性可以消除许多由格式和/或文本大小写引起的不匹配。如果您使用 Trim() 和 .Value2,您的代码应该如下所示。

If Trim(ws1.Cells(i, 1).Value2) = Trim(ws2.Cells(j, 1).Value2) Then
    If Trim(ws1.Cells(i, 17).Value2) <> Trim(ws2.Cells(j, 23).Value2) Then
        ws1.Cells(j, 1).EntireRow.Copy ws3.Cells(newSheetPos, 1)
        newSheetPos = newSheetPos + 1
    Else
    End If
End If

存储在单元格中的值可以被.Text.Value.Value2 引用。 Value2 提供没有任何格式的基础值。 TEXT vs VALUE vs VALUE2 是一篇文章的链接,提供了很好的解释。

【讨论】:

  • 我会试一试,但所有单元格都被格式化为通用格式
  • 这不起作用或者它没有复制任何东西
【解决方案2】:

您好,我现在已经对此进行了排序,我意识到由于偏移量从 1 而不是 0 开始,因此我必须将标准偏移量增加 1,请参见下文

    Dim ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet
    Dim i As Long, j As Long
    Dim newSheetPos As Integer

    Set ws1 = ActiveWorkbook.Sheets("Sheet1")
    Set ws2 = ActiveWorkbook.Sheets("Sheet2")
    Set ws3 = ActiveWorkbook.Sheets("NINO Differences")

    newSheetPos = ws3.Cells(ws3.Rows.Count, 2).End(xlUp).Row

    For i = 1 To ws1.Cells(ws1.Rows.Count, 2).End(xlUp).Row
        For j = 1 To ws2.Cells(ws2.Rows.Count, 2).End(xlUp).Row

            If Trim(ws1.Cells(i, 1).Value2) = Trim(ws2.Cells(j, 1).Value2) Then

                If Trim(ws1.Cells(i, 17).Value2) <> Trim(ws2.Cells(j, 24).Value2) Then
                    ws1.Cells(j, 1).EntireRow.Copy ws3.Cells(newSheetPos, 1)
                    newSheetPos = newSheetPos + 1
                Else
                End If
            Else
            End If

        Next j
    Next i

【讨论】:

  • 谁能想出一种方法来加快这个循环,因为我需要更改标准并运行 18 次来填充不同的工作表?可能会解析到 RAM 中?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-29
  • 2014-03-19
  • 1970-01-01
相关资源
最近更新 更多