昨天有同學(xué)問的,今天說一下!
表頭不同的文件想合并,本來我想說,不規(guī)則,你先整理呀!但是經(jīng)常還是有人問,想必現(xiàn)實真的有亂的不成樣子的表需要合并!那么我們就來聊聊吧!
偷個懶,我就去論壇找個素材,N個Exce文件,每個文件的表頭部分有不同
現(xiàn)在需要合并,一般的程序都是按照位置合并的,并不通用,無法處理這個問題!
我們來看看如何處理!目前推薦的處理方法是PQ,如果你的版本目前不支持,再考慮后面提供的VBA代碼!
Power Query處理這個問題真的是非常的簡單,我們可以考慮獲取到所有表的標題去重,然后去展開數(shù)據(jù)!
Power Query方案
步驟01 :加載Excel文件到PQ
>點擊 【數(shù)據(jù)】- 【獲取數(shù)據(jù)】-【自文件】-【從文件夾】vba選擇文件夾路徑,版本差異,部分略有差異,找到文件夾基本OK
>選擇需要合并的文件所在的文件夾,【打開】,出現(xiàn)的界面中,點擊【轉(zhuǎn)換】。
通過以上步驟把數(shù)據(jù)加載到PQ編輯器中!
▼ 動畫演示-請仔細看
步驟02 :M代碼
>選擇和Name列,右擊刪除其他列!> 點擊 【添加列】 - 【自定義列】 - 輸入公式 ,將二進制數(shù)值轉(zhuǎn)成Excel文件數(shù)據(jù)。
只要下面簡單一句即可!=Table.(List.(.Files("E:\不同表頭")[],.(Excel.(_,true))[Data]{1}))
步驟03 :加載到工作表
點擊 【主頁】- 【關(guān)閉并上載】即可!
通用M函數(shù):左右拖動查看代碼
let
????/*寫上你自己需要合并的路徑*/
????文件夾路徑 = "E:\不同表頭",
????源 = Table.Combine(
????????????List.Combine(List.Transform(Folder.Files(文件夾路徑 )[Content],
????????????????each Table.Buffer(Excel.Workbook(_,true))[Data])
????????????)
????????)
in
????源
友情提示:PQ合并文件雖然簡單,但是有一個致命的坑,網(wǎng)上基本沒人跟大家講vba選擇文件夾路徑,那么就是這里的表是Table,包括定義名稱生成的表、篩選等情況生成的臨時表都在其中,所以經(jīng)常有同學(xué)反饋有重復(fù)數(shù)據(jù)的問題,這里要特別注意一下!
VBA一鍵搞定
▼直接看動畫演示效果吧
VBA源碼:
'功能:不同表頭Excel文件合并
'作者:E精精
'下載:公眾號- Excel辦公實戰(zhàn)
'-------------------------------------------------------------------
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
????'標題和數(shù)據(jù)分別裝入字典備用
????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
????
????'寫入?yún)R總表,沒有的自己建一個
????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的同學(xué),可以了解一下本文的處理思路,小編也是第一次按此思路處理,在第一次循環(huán)把標題和內(nèi)容分別轉(zhuǎn)入字典,這樣避免二次循環(huán),也可以確定結(jié)果列數(shù),標題裝入字典,方便我們根據(jù)標題的名稱確定所屬的列!裝入字典,key用的是表名&文件名,一舉兩得!