ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 633|回复: 15

根据指定的表头文字复制相关列从其它文件里提取数据

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-9-17 13:02 | 显示全部楼层 |阅读模式
本帖最后由 hadky 于 2024-9-17 17:12 编辑

这个宏适用于需要从多个源工作簿中提取特定数据并汇总到一个工作表中的情况。例如,当需要合并多个报表的数据或从不同的数据源中提取信息时,这个宏可以大大提高效率,减少手动操作的错误和时间消耗。

  • 读取当前工作表的表头:


    • 宏首先读取当前工作表的第一行,这些数据被视为表头。
  • 打开文件选择对话框:


    • 使用 FileDialog 对象打开文件选择对话框,让用户选择包含数据的源Excel工作簿。
  • 打开源工作簿并获取第一个工作表:


    • 根据用户选择的文件路径打开源工作簿,并获取其第一个工作表以进行数据匹配和复制操作。
  • 匹配表头并记录匹配的列号:


    • 遍历当前工作表的表头,在源工作表中查找匹配的表头。
    • 如果找到匹配的表头,记录其在源工作表中的列号。
  • 复制匹配列的数据:


    • 对于每个匹配的列,复制源工作表中从第二行开始的数据(跳过表头),并将这些数据粘贴到当前工作表的相应列中的第一个空白行。
  • 避免覆盖现有数据:


    • 在粘贴数据之前,宏会找到目标列的第一个空白行,确保新数据不会覆盖现有数据。
  • 关闭源工作簿:


    • 操作完成后,关闭源工作簿,不保存更改。
      1. Sub CopyMatchingColumnsToCurrentSheet()
      2.     Dim wsCurrent As Worksheet
      3.     Dim wsSource As Worksheet
      4.     Dim sourceWorkbook As Workbook
      5.     Dim fileDialog As FileDialog
      6.     Dim requiredHeaders As Variant
      7.     Dim header As Variant
      8.     Dim colSource As Long
      9.     Dim matchingCols As Object
      10.     Dim lastRow As Long
      11.     Dim targetCol As Long
      12.     Dim targetRow As Long
      13.     Dim colKey As Variant

      14.     ' 使用当前激活的工作表
      15.     Set wsCurrent = ActiveSheet
      16.     Set matchingCols = CreateObject("Scripting.Dictionary") ' 使用字典来存储匹配的列

      17.     ' 读取当前工作表的所有表头
      18.     requiredHeaders = wsCurrent.Rows(1).Value

      19.     ' 创建文件对话框对象
      20.     Set fileDialog = Application.FileDialog(msoFileDialogFilePicker)

      21.     ' 让用户选择源工作簿
      22.     With fileDialog
      23.         .Title = "请选择源工作簿"
      24.         .Filters.Clear
      25.         .Filters.Add "Excel 文件", "*.xls; *.xlsx; *.xlsm; *.xlsb", 1
      26.         .AllowMultiSelect = False
      27.         If .Show = -1 Then
      28.             ' 尝试打开选择的工作簿
      29.             Set sourceWorkbook = Workbooks.Open(.SelectedItems(1))
      30.         Else
      31.             MsgBox "未选择任何工作簿。"
      32.             Exit Sub
      33.         End If
      34.     End With

      35.     ' 使用源工作簿的第一个工作表
      36.     Set wsSource = sourceWorkbook.Sheets(1)

      37.     ' 遍历当前工作表的每一列
      38.     For Each header In requiredHeaders
      39.         header = Trim(header) ' 清除可能的空白字符
      40.         ' 检查源工作表的每一列表头
      41.         For colSource = 1 To wsSource.Cells(1, wsSource.Columns.Count).End(xlToLeft).Column
      42.             If LCase(wsSource.Cells(1, colSource).Value) = LCase(header) Then
      43.                 ' 如果找到匹配的表头,则记录列号
      44.                 matchingCols(header) = colSource
      45.                 Exit For
      46.             End If
      47.         Next colSource
      48.     Next header

      49.     ' 复制匹配的列
      50.     For Each header In matchingCols.Keys
      51.         colSource = matchingCols(header)
      52.         lastRow = wsSource.Cells(wsSource.Rows.Count, colSource).End(xlUp).Row
      53.         ' 找到目标列,粘贴数据
      54.         targetCol = Application.Match(header, wsCurrent.Rows(1), 0)
      55.         If Not IsError(targetCol) Then
      56.             ' 找到第一个空白行
      57.             targetRow = wsCurrent.Cells(wsCurrent.Rows.Count, targetCol).End(xlUp).Row + 1
      58.             ' 仅复制数据,跳过表头
      59.             wsSource.Range(wsSource.Cells(2, colSource), wsSource.Cells(lastRow, colSource)).Copy
      60.             wsCurrent.Cells(targetRow, targetCol).PasteSpecial Paste:=xlPasteValues
      61.             Application.CutCopyMode = False
      62.         Else
      63.             MsgBox "未找到匹配的表头: " & header
      64.         End If
      65.     Next header

      66.     ' 关闭源工作簿,不保存更改
      67.     sourceWorkbook.Close SaveChanges:=False

      68.     ' 提示完成
      69.     MsgBox "已根据指定的表头文字复制相关列。"
      70. End Sub
      复制代码
      image.png image.png image.jpg image.jpg
    • 源表数据


示例.rar

176.74 KB, 下载次数: 22

TA的精华主题

TA的得分主题

发表于 2024-9-17 14:41 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 ykcbf1100 于 2024-9-17 14:44 编辑

楼主上个附件呗
没用数组,效率不高。

TA的精华主题

TA的得分主题

发表于 2024-9-19 10:36 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2024-9-19 11:21 | 显示全部楼层
  1. Sub qs()
  2.     Application.ScreenUpdating = False: Application.DisplayAlerts = False
  3.     Dim arr, i, wb As Workbook, xb As Workbook, FileName, brr, rw
  4.     Sheet1.Range("a1").Offset(1).Resize(50000, 20).Clear
  5.      brr = Sheet1.Range("a1").CurrentRegion.Value
  6.     Set wb = ThisWorkbook
  7.     '可多选文件对话框
  8.     FileName = Application.GetOpenFilename(FileFilter:="Excel 工作簿文件 (*.xls*),*.xls*", Title:="请选择文件", MultiSelect:=True)
  9.     If Not IsArray(FileName) Then
  10.         MsgBox "没有选择文件"
  11.         Exit Sub
  12.     End If
  13.     With wb.Sheets(1)
  14.         For Each f In FileName '循环已经选了文件
  15.             rw = .Cells(Rows.Count, 1).End(3).Row + 1
  16.             Set xb = Workbooks.Open(f, 0)
  17.             arr = xb.Sheets(1).Range("a1").CurrentRegion
  18.             For b = 1 To UBound(brr, 2)
  19.                 For a = 1 To UBound(arr, 2)
  20.                     If brr(1, b) = arr(1, a) Then
  21.                         .Cells(rw, b).Resize(UBound(arr), 1) = Application.Index(arr, 0, a)
  22.                         Exit For
  23.                     End If
  24.                 Next a
  25.             Next b
  26.             xb.Close (0)
  27.             .Rows(rw).Delete
  28.         Next f
  29.     End With
  30.     Application.ScreenUpdating = True: Application.DisplayAlerts = True
复制代码

TA的精华主题

TA的得分主题

发表于 2024-9-19 11:23 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2024-9-19 11:24 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
试试........

示例.rar

420.42 KB, 下载次数: 46

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-9-19 20:54 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-9-19 22:50 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
有一个问题是会清掉现有文档的存在记录,第二个是如果有去重的功能更好了

TA的精华主题

TA的得分主题

发表于 2024-9-20 09:16 | 显示全部楼层
hadky 发表于 2024-9-19 22:50
有一个问题是会清掉现有文档的存在记录,第二个是如果有去重的功能更好了

敢问一下,你这清除现有文档的存在记录,指的是源数据的工作表吗?
再问一下,你去重是按什么来去重的?去重后,日期肯定保留不了了,那还算按字段来提取数据吗?
本想下手了,但没搞清楚状况,不敢下手啊。

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-10-23 10:31 | 显示全部楼层
清除现有文档存在的记录,汇总表里原有的数据会清掉,
二个是,如果加载来源表里有重复的数据,应该是要去除的,应该把首列的头当做key
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-12-25 15:37 , Processed in 0.034576 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表