【问题标题】:Excel: comparing names in two different sheetsExcel:比较两个不同工作表中的名称
【发布时间】:2016-02-22 16:10:32
【问题描述】:

我有两张 Excel 表格,每张大约 500 行。工作表 A 有一个名称列 E),工作表 B 有两个名称列用于小名称和大名称 (H&I)。我想创建一个循环来遍历并比较这些列,如果找到匹配项,则将此匹配项粘贴到新工作表中。

进一步说明:

在工作表 B 上,两个名称列类似于 Cigna 和 Cigna Co,因此它们并不总是重复相同的名称,而在工作表 A 上,名称可能是 Cigna,因此它们并不总是准确的。但工作表 A 的名称必须与工作表 B 上的 1 或两个名称匹配。

【问题讨论】:

  • 为什么不直接使用工作表公式。一些countif() 公式在这里会有很长的路要走。是否所有三列都需要包含名称才能成为“匹配”,或者只是名称不止一次是任何列?您的问题对细节有点轻描淡写。
  • @ JNevill 在工作表 B 上,两个名称列类似于 Cigna 和 Cigna Co,因此它们并不总是重复相同的名称,而在工作表 A 上,名称可能是 Cigna,所以它们不是不过总是准确的。但工作表 A 的名称必须与工作表 B 上的 1 或两个名称匹配。

标签: excel vba


【解决方案1】:

这样的事情是一个简单的循环和记录,然后看看第一张纸上是否有任何东西在第二张纸上。

不确定您的大小名称情况如何,所以我检查了这两列

在您的 VBA IDE 中,转到工具菜单并选择引用。选择“Microstoft ActiveX data objects 2.8 Library。这将用于记录集。

Private Sub CommandButton1_Click()
    Dim rs As New ADODB.Recordset
    Dim ws As Excel.Worksheet
    Dim ws2 As Excel.Worksheet
    Dim lRow As Long
    Dim lRowOut As Long

    Set ws = ActiveWorkbook.Sheets("Sheet1")
    ws.Activate

    Set ws2 = ActiveWorkbook.Sheets("Sheet3")

    'Add fields to your recordset for storing data.
    With rs
        .Fields.Append "Row", adInteger
        .Fields.Append "Name", adChar, 25
        .Open
    End With

    'Loop through and record the name
    lRow = 1
    Do While lRow <= ws.UsedRange.Rows.count

        rs.AddNew
        rs.Fields("Row").Value = lRow
        rs.Fields("Name").Value = ws.Range("E" & lRow).Value
        rs.Update

        lRow = lRow + 1
        ws.Range("A" & lRow).Activate
    Loop

    If rs.EOF = False Then
        rs.MoveFirst
    End If

    'Switch to the second worksheet
    Set ws = Nothing
    Set ws = ActiveWorkbook.Sheets("Sheet2")
    ws.Activate

    'Loop through and see if anything on this sheet was on the first sheet.
    lRow = 1
    lRowOut = 1
    Do While lRow <= ws.UsedRange.Rows.count

        'Check if the column H name was recorded from the first sheet
        rs.Filter = ""
        rs.Filter = "Name='" & ws.Range("H" & lRow).Value & "'"
        If rs.RecordCount = 0 Then
            rs.Filter = ""
            rs.Filter = "Name='" & ws.Range("I" & lRow).Value & "'"
            If rs.RecordCount > 0 Then
                'It has a date, delete the current row
                ws2.Range("A" & lRowOut).Value = rs.Fields("Name").Value
                lRowOut = lRowOut + 1
            End If
        ElseIf rs.RecordCount > 0 Then
            'It has a date, delete the current row
            ws2.Range("A" & lRowOut).Value = rs.Fields("Name").Value
            lRowOut = lRowOut + 1
        End If

        lRow = lRow + 1
        ws.Range("A" & lRow).Activate
    Loop
End Sub

如果您想查找您在评论中所说的名称的一部分,您可以使用点赞。将过滤器行更改为类似的内容。

rs.Filter = "Name LIKE '%" & ws.Range("I" & lRow).Value & "%'"

【讨论】:

  • 非常感谢您的帮助!
【解决方案2】:

使用公式而不是 VBA 执行此操作,我会在新工作簿的 A1 中粘贴一个公式,如下所示。假设您的“工作表 A”在 Sheet1 上的 Book1 中,而“工作表 B”中的 H 和 I 列是 Sheet1 上的 Book2:

=if(countif([Book2]Sheet1!H:I, [Book1]Sheet1!E1)>1, [Book1]Sheet1!A1, "")

这表示“如果在 Book2 的 Sheet1 中我的列 H 和 I 中,Book1 的 Sheet1 中单元格 E1 的名称最后匹配,然后从 Book1 的 Sheet1 上的单元格 E1 中获取名称”

这将留下大量空白,但此时您可以过滤或整理它们。

如果要求比这更复杂,例如跨三列中的任何一个匹配,那么您可以添加多个 CountIf() 公式的结果并测试它们是否 > 1,或者为每个公式执行一个 Countif()列,然后合并结果,排序/过滤,鲍勃是你的叔叔。

如果这将成为您经常做的事情,那么投资 VBA 路线可能是值得的,因为这将减少一些手动工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多