分享

表头不同的Excel表格如何合并?

 Excel办公实战 2021-06-29

表头不同的文件想合并,本来我想说,不规则,你先整理呀!但是经常还是有人问,想必现实真的有乱的不成样子的表需要合并!那么我们就来聊聊吧!

偷个懒,我就去论坛找个素材,N个Exce文件,每个文件的表头部分有不同

现在需要合并,一般的程序都是按照位置合并的,并不通用,无法处理这个问题!

我们来看看如何处理!目前推荐的处理方法是PQ,如果你的版本目前不支持,再考虑后面提供的VBA代码!

Power Query处理这个问题真的是非常的简单,我们可以考虑获取到所有表的标题去重,然后去展开数据!

Power Query方案


步骤01 :加载Excel文件到PQ

> 点击 【数据】- 【获取数据】- 【自文件】-【从文件夹】,版本差异,部分略有差异,找到文件夹基本OK

> 选择需要合并的文件所在的文件夹,【打开】,出现的界面中,点击【转换】。

通过以上步骤把数据加载到PQ编辑器中!


▼ 动画演示-请仔细看


步骤02 :M代码

选择Content和Name列,右击删除其他列!
> 点击 【添加列】 - 【自定义列】 - 输入公式 ,将二进制数值转成Excel文件数据。

只要下面简单一句即可!
= Table.Combine(List.Transform(Folder.Files("E:\不同表头")[Content],each Table.Buffer(Excel.Workbook(_,true))[Data]{1}))





步骤03 :加载到工作表

点击 【主页】- 【关闭并上载】即可!


通用M函数:左右拖动查看代码
let
    /*写上你自己需要合并的路径*/
    文件夹路径 = "E:\不同表头",
    源 = Table.Combine(
            List.Combine(List.Transform(Folder.Files(文件夹路径 )[Content],
                each Table.Buffer(Excel.Workbook(_,true))[Data])
            )
        )
in
    源

友情提示:PQ合并文件虽然简单,但是有一个致命的坑,网上基本没人跟大家讲,那么就是这里的表是Table,包括定义名称生成的表、筛选等情况生成的临时表都在其中,所以经常有同学反馈有重复数据的问题,这里要特别注意一下!


VBA一键搞定

▼ 
直接看动画演示效果吧




VBA源码:

'功能:不同表头Excel文件合并
'作者:E精精
'下载:公众号- Excel办公实战
'-------------------------------------------------------------------
Sub ComData()
    Dim sPath As String
    '选择文件夹
    With Application.FileDialog(msoFileDialogFolderPicker)
        If .Show Then
            sPath = .SelectedItems(1)
            sPath = sPath & IIf(VBA.Right(sPath, 1) = "\", "", "\")
        Else
            End
        End If
    End With
    
    Dim file As String, ShtCount As Long
    Dim dTitle As Object, dData As Object
    Dim Sht As Worksheet, wb As Workbook
    file = Dir(sPath & "*.xl*")
    Set dTitle = CreateObject("Scripting.dictionary")
    Set dData = CreateObject("Scripting.dictionary")
    
    Dim ShtName As String, wbName As String
    
    t = Timer
    '标题和数据分别装入字典备用
    Application.ScreenUpdating = False
    Do While Len(file) > 0
        Set wb = Workbooks.Open(sPath & file, False, True)
        For Each Sht In wb.Worksheets
            ShtCount = ShtCount + 1
            arr = Sht.Range("A1").CurrentRegion.Value
            ShtName = Sht.Name '
工作表名称
            wbName = Split(wb.Name, ".")(0) '文件名
            dData(wbName & "|" & ShtName) = arr
            For i = 1 To UBound(arr, 2)
                If Not dTitle.exists(arr(1, i)) Then
                   k = k + 1
                   dTitle(arr(1, i)) = k
                End If
            Next
        Next
        
        wb.Close 0
        file = Dir
    Loop
    Application.ScreenUpdating = True
    
    Dim brr()
    '
+2 文件名+表名
    ReDim brr(1 To 100000, 1 To dTitle.Count + 2)
    
    For Each eve In dData.keys()
        arr = dData(eve)
        For i = 2 To UBound(arr)
            n = n + 1
            tp = Split(eve, "|")
            brr(n, 1) = tp(0) '文件名
            brr(n, 2) = tp(1) '
表名
            For j = 1 To UBound(arr, 2)
                brr(n, dTitle(arr(1, j)) + 2) = arr(i, j)
            Next
        Next
    Next
    
    '写入汇总表,没有的自己建一个
    With Sheets("汇总表")
        .Cells.Clear
        .Range("A1:B1") = Array("文件名", "表名")
        .Range("C1").Resize(1, dTitle.Count) = dTitle.keys()
        .Range("A2").Resize(n, dTitle.Count + 2) = brr
    End With
    
    MsgBox "汇总完成!共汇总:" & ShtCount & "个表!" _
    & vbCrLf & "用时:" & Format(Timer - t, "0.00s")
End Sub


懂VBA的同学,可以了解一下本文的处理思路,小编也是第一次按此思路处理,在第一次循环把标题和内容分别转入字典,这样避免二次循环,也可以确定结果列数,标题装入字典,方便我们根据标题的名称确定所属的列!装入字典,key用的是表名&文件名,一举两得!

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多