這篇帖子緣起于在微博上的一個(gè)討論:

原帖提出用PowerQuery來合并同一文件夾下所有工作簿中的所有工作表數(shù)據(jù),我做了一個(gè)補(bǔ)充:
如果單個(gè)Excel或sheet很復(fù)雜,可以基于處理完的單個(gè)表格建立自定義函數(shù),這樣合并時(shí)直接調(diào)用該函數(shù),就可以解決復(fù)雜表格的合并問題。
當(dāng)時(shí)我沒說清楚細(xì)節(jié),所以有網(wǎng)友回復(fù)說:
還是Excel.Workbook()批量提取內(nèi)容穩(wěn)妥
其實(shí)我說的自定義函數(shù)也是基于Excel.Workbook()這個(gè)函數(shù),只是區(qū)別在于:對(duì)于復(fù)雜表格,用Excel.Workbook()獲取所有Excel文件中所有Sheets的數(shù)據(jù)后,我并不展開,而是就展開單個(gè)Sheet,進(jìn)行處理,然后基于此建立函數(shù),再把此函數(shù)應(yīng)用到其他尚未展開的Sheets上去。
說起來比較抽象,用一個(gè)實(shí)際例子來演示下這個(gè)思路。
原始數(shù)據(jù)
原始數(shù)據(jù)是類似下面這樣的表格:
我們只需要提取紅圈中的數(shù)據(jù),將每一個(gè)表格都降維(壓扁)變成一條單一的記錄。
這樣的表格有無數(shù)個(gè),散布在N個(gè)Excel文件中M個(gè)Sheets中。
第一步:用Excel.Workbook()函數(shù)獲取所有表格,但是并不展開
如下圖所示,引入來自于文件夾的源之后,調(diào)用Excel.Workbook()函數(shù),獲取到所有表格的數(shù)據(jù),并保存在Table中,不展開。

第二步:提取數(shù)據(jù),這一步是分歧所在
對(duì)于簡(jiǎn)單表格(或曰規(guī)范表格,也就是表格第一行是列字段,以后每一行都是一條完整的記錄,沒有合并單元格),可以直接展開【Data】列,把展開的表格第一行提升為標(biāo)題,篩選掉其余不需要的表格標(biāo)題行(不過我一般喜歡先把【Data】列的每一個(gè)Table都用Table.PromoteHeaders()函數(shù)來把表格第一行作為標(biāo)題,然后再展開,這樣就可以節(jié)省一些步驟且不容易出錯(cuò)),這樣就得到所需數(shù)據(jù)了。
但是實(shí)際工作中,我們有很大幾率遇到這個(gè)例子中這樣的復(fù)雜表格,讓我們?cè)倩仡櫹拢?/p>
[圖片上傳失敗...(image-827bcf-1583634863355)]
對(duì)于這樣復(fù)雜的表格,如果直接展開第一步得到的【Data】列,得到的結(jié)果就是如上圖中這樣的N*M個(gè)表格依次從上至下排列形成的一個(gè)巨大且復(fù)雜無比的大表格(由于表格太大太復(fù)雜,我截圖都不好截。有興趣的可以找一個(gè)很復(fù)雜的表格來親自試試看),這樣的表格,根據(jù)我寡陋的見識(shí),簡(jiǎn)直不知道如何處理才好。
所以在提取數(shù)據(jù)這一步,我的做法稍有不同:
- 展開第一步中【Data】列中的任意一個(gè)Table,然后對(duì)其進(jìn)行降維處理,得到我需要的形式——變成有很多列的一行數(shù)據(jù)(注:如果您的復(fù)雜表格不同,需要的結(jié)果不同,最后得到的不一定就是有很多列的一行數(shù)據(jù))。
- 基于上面的一系列步驟,建立一個(gè)自定義函數(shù)(假設(shè)叫fn),其參數(shù)就是第一步得到的【Data】列中的Table。
- 在【第一步】的結(jié)果中為【Data】列中的每一行調(diào)用這個(gè)自定義函數(shù)fn(下面截圖中我是通過新增一個(gè)【自定義】列來調(diào)用自定義函數(shù)fn)。

這樣,當(dāng)我們展開【自定義】列時(shí),就可以直接得到我們所需的數(shù)據(jù)了。
小結(jié)
如果表格很規(guī)范,結(jié)構(gòu)很簡(jiǎn)單,完全沒必要用自定義函數(shù),直接用Excel.Workbook()函數(shù)獲取表格,然后展開(是否先把第一行提升為標(biāo)題看個(gè)人喜歡)即可;如果遇到很復(fù)雜的表格,直接展開應(yīng)該是行不通的,這時(shí)就需要化整為零,通過自定義函數(shù)先把單個(gè)表格的處理步驟封裝起來,然后再對(duì)其他表格調(diào)用該函數(shù)即可。