You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用VBA与VLOOKUP实现Excel按姓氏匹配复制行数据

嘿,我来帮你搞定这个Excel数据匹配提取的需求!根据你的描述,我整理了两种实用方案,不管你用的是新版还是旧版Excel都能轻松实现👇

解决方案:基于姓氏匹配Excel工作表并提取对应行

方法一:使用Excel公式(适合数据量不大的场景)

步骤1:提取Data2中的姓氏

假设Data2的姓名列在A列,先在Data2的空白列(比如B列)添加公式提取姓氏:

  • 在B2单元格输入:=LEFT(A2,1)(如果涉及复姓,后面会讲调整方法)
  • 下拉填充到所有姓名行,这样B列就得到了Data2中所有人员的姓氏

步骤2:在新工作表中筛选匹配行

新建一个工作表命名为「匹配结果」,然后根据你的Excel版本选择对应公式:

如果你用的是Excel 365/2021(支持FILTER函数)

在「匹配结果」的A2单元格输入:

=FILTER(Data1!A:Z, ISNUMBER(MATCH(LEFT(Data1!A:A,1), Data2!B:B, 0)))

按下回车后,公式会自动提取Data1中所有姓氏和Data2匹配的完整行。

公式解释

  • LEFT(Data1!A:A,1):提取Data1每行姓名的第一个字(姓氏)
  • MATCH(..., Data2!B:B, 0):检查这个姓氏是否存在于Data2的姓氏列表中
  • ISNUMBER(...):将匹配结果转为布尔值(存在则为TRUE)
  • FILTER(Data1!A:Z, ...):筛选出Data1中符合条件的所有行

如果你用的是旧版Excel(无FILTER函数)

在「匹配结果」的A2单元格输入数组公式(输入后按Ctrl+Shift+Enter触发):

=IFERROR(INDEX(Data1!A:A, SMALL(IF(ISNUMBER(MATCH(LEFT(Data1!$A$2:$A$1000,1), Data2!$B$2:$B$100,0)), ROW(Data1!$A$2:$A$1000)), ROW(A1))), "")

然后向右拖动填充到所有列,再向下拖动填充到没有数据的行即可。

注意:公式里的$A$2:$A$1000$B$2:$B$100要根据你的实际数据范围调整。

方法二:使用VBA代码(适合数据量大的场景)

如果你的Data1有几百上千行,公式可能会卡顿,这时候用VBA更高效:

  1. 打开Excel,按下Alt+F11打开VBA编辑器
  2. 右键点击左侧的工作簿名称,选择「插入」→「模块」
  3. 粘贴以下代码:
Sub MatchAndCopyRows()
    Dim wsData1 As Worksheet, wsData2 As Worksheet, wsResult As Worksheet
    Dim lastRowData1 As Long, lastRowData2 As Long, i As Long, j As Long
    Dim surname As String, matchFound As Boolean
    
    ' 初始化工作表对象
    Set wsData1 = ThisWorkbook.Worksheets("Data 1")
    Set wsData2 = ThisWorkbook.Worksheets("Data 2")
    ' 创建新的结果工作表
    Set wsResult = ThisWorkbook.Worksheets.Add(After:=wsData2)
    wsResult.Name = "匹配结果"
    
    ' 复制Data1的表头到结果表
    wsData1.Rows(1).Copy wsResult.Rows(1)
    
    ' 获取数据的最后一行行号
    lastRowData1 = wsData1.Cells(Rows.Count, "A").End(xlUp).Row
    lastRowData2 = wsData2.Cells(Rows.Count, "A").End(xlUp).Row
    
    ' 遍历Data1的每一行数据
    For i = 2 To lastRowData1
        ' 提取当前行的姓氏(单字姓)
        surname = Left(wsData1.Cells(i, "A").Value, 1)
        matchFound = False
        
        ' 在Data2中查找匹配的姓氏
        For j = 2 To lastRowData2
            If Left(wsData2.Cells(j, "A").Value, 1) = surname Then
                matchFound = True
                Exit For ' 找到匹配就跳出循环,提高效率
            End If
        Next j
        
        ' 如果匹配成功,复制当前行到结果表
        If matchFound Then
            wsData1.Rows(i).Copy wsResult.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)
        End If
    Next i
    
    MsgBox "匹配完成!结果已经保存到「匹配结果」工作表中。", vbInformation
End Sub
  1. 按下F5运行代码,等待完成后会弹出提示框。

针对复姓的调整

如果你的数据里有复姓(比如欧阳、司马),需要修改提取姓氏的逻辑:

  • 公式版:把提取姓氏的公式改成:
    =IF(OR(LEFT(A2,2)={"欧阳","司马","上官","诸葛"}),LEFT(A2,2),LEFT(A2,1))
    
    可以根据实际复姓列表继续添加到大括号里。
  • VBA版:把提取姓氏的代码改成:
    ' 定义复姓列表
    Dim compoundSurnames As Variant
    compoundSurnames = Array("欧阳", "司马", "上官", "诸葛")
    ' 判断是否是复姓
    surname = Left(wsData1.Cells(i, "A").Value, 2)
    If IsError(Application.Match(surname, compoundSurnames, 0)) Then
        surname = Left(wsData1.Cells(i, "A").Value, 1)
    End If
    

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

火山引擎 最新活动