ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] 多薄多表合并(不限表头位置和顺序)

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2018-10-19 01:21 | 显示全部楼层 |阅读模式
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
也是找了很多地方没有找到表头比较乱的合并代码,自己尝试写的,有些乱。希望得到前辈指点,优化。
另外我想实现无表头的列也合并进来,有时间再去尝试吧。
11.png


多薄多表合并(不限表头位置和顺序).zip (83.69 KB, 下载次数: 745)


补充内容 (2018-11-22 19:03):
七楼更新代码

补充内容 (2019-4-29 22:56):
24楼 附上整理后的合并代码,另附拆分代码

补充内容 (2019-5-6 23:48):
把表头匹配的关系改了一下:
24楼,分表表头包含总表表头
30楼,总表表头是分表相似表头的集合,用/或、号分隔的。
貌似这样更合理一些,不至于跑偏得到意想不到的结果。
不过麻烦之处是你需要知道分表之中可能有哪些表头

例如说:我要合并各分表的入学的时间,有的表可能叫入学年度,有的表叫入学时间,有的表又可能叫入学年月。
24楼的方法总表表头a1单元格写成:入学,但是有可能会匹配到分表中叫入学方式之类的数据列
30楼的方法总表表头a1单元格写成:入学年度/入学时间/入学年月,这样可以准确匹配这几个表的数据

补充内容 (2019-5-19 00:02):
33楼 合并修改,增加几个拆分代码

补充内容 (2019-6-2 13:22):
楼下为置顶的最新版本

评分

5

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-2-19 22:12 | 显示全部楼层
本帖最后由 liuxi001 于 2020-2-20 18:09 编辑
paul1115 发表于 2019-4-4 21:44
改成菜单调用窗体会更好些,这样一来就可以省去先把工具拷到指定文件夹里面的麻烦了,直接选择待合并工作表 ...

合并、拆分与汇总v0.6.zip (343.45 KB, 下载次数: 957)
36.jpg
37.jpg
38.jpg


补充内容 (2021-2-17 14:35):
新版更新在QQ群 文件名etools

评分

3

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-10-23 20:06 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 liuxi001 于 2018-10-26 10:07 编辑
  1. Sub 多薄多表合并()
  2.     Dim zTab(1 To 65535, 1 To 100), fTab, zTitle, 总表表头行, 总表列数, 分表表头行, 分表尾行
  3.     Dim sh As Worksheet, Wb As Workbook, 选择 As Range, 分表尾单元格 As Range, dic
  4.     Set dic = CreateObject("scripting.dictionary")
  5.     '获取总表表头行号、列数
  6.     '************************************************************
  7.     '方法1:鼠标单击选择表头行
  8. '    On Error Resume Next
  9. '    Set 选择 = Application.InputBox("请选择总表表头所在行的任意单元格", "选择", Type:=8)
  10. '    On Error GoTo 0
  11. '    If 选择 Is Nothing Then
  12. '        Exit Sub
  13. '    Else
  14. '        总表表头行 = Val(Split(选择.Address, "$")(2))
  15. '    End If
  16.     '************************************************************
  17.     '方法2:总表第一行为表头
  18.     总表表头行 = 1
  19.     '************************************************************
  20.     zTitle = Range(Cells(总表表头行, 1), Cells(总表表头行, Cells(总表表头行, Columns.Count).End(xlToLeft).Column)).Value
  21.     If Not IsArray(zTitle) Then
  22.         Exit Sub
  23.     Else
  24.         总表列数 = UBound(zTitle, 2)
  25.     End If
  26.     t = Timer
  27.     '设置循环目录
  28.     p = ThisWorkbook.Path & ""
  29.     F = Dir(p & "*.xls*")
  30.     Application.ScreenUpdating = False
  31.     '工作薄名不为空时循环
  32.     Do While F <> ""
  33.         '工作薄名和总表文件名相同则跳过
  34.         If F <> ThisWorkbook.Name Then
  35.             Set Wb = GetObject(p & F)
  36.             '工作表循环
  37.             For Each sh In Wb.Sheets
  38.                 '****************************************************
  39.                 '分表表头行号'出现次数最多的为表头行,防止其它行有与表头有相似名称
  40.                 For j = 1 To 总表列数
  41.                     Set fTany = sh.Range("1:100").Find(zTitle(1, j), , xlFormulas, xlPart, xlByRows, xlNext)
  42.                     If Not fTany Is Nothing Then
  43.                         dic(fTany.Row) = dic(fTany.Row) + 1
  44.                     End If
  45.                 Next
  46.                 For Each ele In dic.keys
  47.                     If dic(ele) = Application.Max(dic.items) Then
  48.                         分表表头行 = ele
  49.                         Exit For
  50.                     End If
  51.                 Next
  52.                 dic.RemoveAll
  53.                 '****************************************************
  54.                 '分表列数、尾行、数据
  55.                 Set 分表尾单元格 = sh.Cells.Find("*", , xlFormulas, xlPart, xlRows, xlPrevious)
  56.                 If Not 分表尾单元格 Is Nothing Then
  57.                     分表尾行 = 分表尾单元格.Row
  58.                     分表列数 = sh.Cells(分表表头行, sh.Columns.Count).End(xlToLeft).Column
  59.                     fTab = sh.Range(sh.Cells(分表表头行, 1), sh.Cells(分表尾行, 分表列数)).Value
  60.                     分表行数 = UBound(fTab, 1)
  61.                     ReDim ztofcol(1 To 总表列数)
  62.                     '*************************************************
  63.                     '总表表头在分表中的列号(ztofcol)
  64.                     For i = 1 To 总表列数
  65.                         For j = 1 To 分表列数
  66.                             If fTab(1, j) <> "" Then
  67.                                 If ztofcol(i) = 0 And (InStr(zTitle(1, i), fTab(1, j)) > 0 Or InStr(fTab(1, j), zTitle(1, i)) > 0) Then
  68.                                     ztofcol(i) = j
  69.                                     '在分表中找到表头后计数
  70.                                     TitleCnt = TitleCnt + 1
  71.                                     Exit For
  72.                                 End If
  73.                             End If
  74.                         Next
  75.                     Next
  76.                     '*************************************************
  77.                     '分表无表头列
  78.                     
  79.                     '待增功能,合并分表中无表头的列数据
  80.                     '*************************************************
  81.                     n = n + 1
  82.                     '分表数据写入总表数组
  83.                     If TitleCnt > 0 Then
  84.                         For i = 2 To 分表行数
  85.                             m = m + 1
  86.                             For j = 1 To 总表列数
  87.                                 If Not IsEmpty(ztofcol(j)) Then
  88.                                     zTab(m, j) = fTab(i, ztofcol(j))
  89.                                 End If
  90.                             Next
  91.                             zTab(m, 2) = Left(Wb.Name, InStr(Wb.Name, ".") - 1) & "_" & sh.Name
  92.                             zTab(m, 1) = m
  93.                         Next
  94.                         '清空分表表头与总表表头对应关系数组
  95.                         Erase ztofcol
  96.                         TitleCnt = 0
  97.                     End If
  98.                 End If
  99.             Next
  100.             Workbooks(F).Close False
  101.         End If
  102.         F = Dir
  103.     Loop
  104.     If m > 0 Then
  105.         Cells(总表表头行 + 1, 1).Resize(Rows.Count - 总表表头行, Columns.Count).ClearContents
  106.         '*****************************************************
  107.         '设置文本格式,超过15位的数字建议设置文本格式
  108.         Range("A:B").NumberFormat = "@"
  109.         '*****************************************************
  110.         Cells(总表表头行, 1) = "序号"
  111.         Cells(总表表头行, 2) = "数据来源"
  112.         Cells(总表表头行 + 1, 1).Resize(m, 总表列数 + 2) = zTab
  113.     End If
  114.     Application.ScreenUpdating = True
  115.     Cells(11, 总表列数 + 2) = "共合并了" & n & "个文件," & m & "行数据。" & "用时:" & Format(Timer - t, "0.00") & "秒"
  116.     Cells(12, 总表列数 + 2) = "说明:1.把此工作薄复制到要合并的文件夹下;"
  117.     Cells(13, 总表列数 + 2) = "      2.在本表中填写好要合并的列字段名称,例如本表的第1行;"
  118.     Cells(14, 总表列数 + 2) = "      3.不限制分表的表头位置和顺序,但是分表要合并的列字段名要与总表相同(可以是包含关系,如客户姓名—姓名)"
  119.     Cells(15, 总表列数 + 2) = "      4.支持EXCEL2003,如果数据超过65536行请选择2007版或以上版本,并自行修改数组声明zTab(1 To 1000000, 1 To 100)"
  120. End Sub
  121. Sub cl()
  122.     Range(Cells(2, 1), Cells(Rows.Count, Columns.Count)).ClearContents
  123. End Sub
复制代码
修改了一下,添加了序号列和数据来源列。


补充内容 (2019-4-30 01:02):
这段代码废了,直接24楼  

评分

3

查看全部评分

TA的精华主题

TA的得分主题

发表于 2018-11-14 15:41 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2018-11-14 15:45 | 显示全部楼层
liuxi001 发表于 2018-10-23 20:06
修改了一下,添加了序号列和数据来源列。

鼓励分享,挺一个先!

TA的精华主题

TA的得分主题

发表于 2018-11-14 22:40 | 显示全部楼层
修改后的代码测试没有反应,原来反倒是正常的

TA的精华主题

TA的得分主题

发表于 2018-11-14 22:55 | 显示全部楼层
我正在找这个工具,非常感谢!

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-11-15 01:26 | 显示全部楼层
thzss 发表于 2018-11-14 22:40
修改后的代码测试没有反应,原来反倒是正常的


试了一下,确实有问题,重新发一下。
多薄多表合并(不限表头位置和顺序).zip (38.26 KB, 下载次数: 730)

TA的精华主题

TA的得分主题

发表于 2018-11-15 16:45 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2018-11-15 16:51 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2018-12-10 17:19 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-26 07:23 , Processed in 0.046803 second(s), 17 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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