PowerQuery處理列名包含合并單元格的幾種思路

一直沒能說服公司小伙伴不要用合并單元格,因此我接收到的原始表格總是充滿了各種合并單元格。最頭痛的是列名有合并的。比如下面這樣的(且不說這難看的屎黃):


merged_cells.png

列名有合并單元格也就罷了,關(guān)鍵是這合并單元格也是動(dòng)態(tài)的——不同時(shí)間提交過來的表格,合并單元格的具體內(nèi)容會(huì)有變化。真是整死個(gè)人么也幺哥,整死個(gè)人么也幺哥……
目前總結(jié)了四種方法:

一、釜底抽薪法

最牛逼最有效的當(dāng)然是說服提供表格的小伙伴停止使用坑爹的合并單元格(以及莫名其妙的底紋)。

二、自己辛苦手動(dòng)修改法

就是每次收到excel表格后,我自己手動(dòng)取消合并單元格,把列名整理成合規(guī)的格式。
但作為一個(gè)超級(jí)懶人,每次來了一個(gè)表格都要手動(dòng)改半天,太不優(yōu)雅了。于是有了第三種方法。

三、利用list.zip()函數(shù)合成重命名列名表達(dá)式法

用powerquery大法,引入數(shù)據(jù)源后,合并單元格會(huì)被打散。以下是關(guān)鍵步驟:
1.將合并單元格的第一行提升為表格標(biāo)題,這樣一來,之前是合并單元格的列名會(huì)變成類似于“column5”、“column6”之類的,其他都是正常的列名。而第二行的數(shù)據(jù),正常列名下面的值變成了null,以“columnX”開頭的列下面是我們要提取出來的列名,如截圖中“投放媒體”下面的四個(gè)值。
2.利用powerquery訪問行的方法,得到表格第一行的值,基本函數(shù)是Record.FieldValues()。
3.然后將第二步得到的list和Table.ColumnNames()函數(shù)獲取的表格列名用List.Zip()函數(shù)進(jìn)行合并,得到一個(gè)包含list的list,為敘述方便,將其命名為M。這時(shí)用List.Transform(M,Combiner.CombineTextByDelimiter(""))將M中每個(gè)子list的元素合并成一個(gè),這樣我們就得到一個(gè)近似于完美的目標(biāo)表格列名。之所以說,近似完美,是因?yàn)镸進(jìn)行這樣的變換后(命名為MM),其中包含“Column6百度信息流作”這樣的元素,我們需要將“Column6”這樣的字母和數(shù)字去掉,只保留文本。
4.于是用List.Transform(MM,each Text.Remove(_,List.Union({{"A".."z"},{"0".."9"}})))將數(shù)字和字母去掉,保留中文。
5.這樣我們就得到一個(gè)TargetColumnName的list。再次用List.Zip()函數(shù)構(gòu)造重命名列名的表達(dá)式:Table.RenameColumns(table,List.Zip({OriginalColumnName,TargetColumnName}))。
6.這樣就基本完成了表格的重命名工作。不過還留下了一個(gè)小尾巴,就是“投放媒體”對(duì)應(yīng)索引位置的第二行值是類似于“網(wǎng)站制作”這樣的,所以最后還要把“投放媒體”這樣的批量替換掉。

這個(gè)方法繁瑣且留有尾巴,我還是想找一個(gè)更優(yōu)雅的辦法來解決合并單元格動(dòng)態(tài)命名的問題。于是有了終極大法。

四、終極大法:Table.TransformColumnNames()函數(shù)大法

這個(gè)函數(shù)太復(fù)雜,我也沒完全搞懂,主體結(jié)構(gòu)是:

Table.TransformColumnNames(table as table, nameGenerator as function, optional options as nullable record) as table

爬網(wǎng)并試驗(yàn),最后得出了下面的這個(gè)表達(dá)式:

Table.TransformColumnNames(#"Promoted Headers",each 
if 
  Text.Contains(_,"Column") 
then 
  Record.FieldValues(#"Promoted Headers"{0}){(List.PositionOf(Table.ColumnNames(#"Promoted Headers"),_))} 
else 
  if  _="投放媒體" 
  then 
  Record.FieldValues(#"Promoted Headers"{0}){(List.PositionOf(Table.ColumnNames(#"Promoted Headers"),_))} 
  else  _
 )

超級(jí)長(zhǎng)的一行代碼,我的思路是,利用if...then...else結(jié)構(gòu),逐一判斷表格列名的每一個(gè)元素是否包含“Column”,如果包含,那么它就是需要變換的列名,如果不包含,那么就(暫時(shí))不做任何操作。

那么,怎么變換呢?還是最基礎(chǔ)的思路,用列名對(duì)應(yīng)的表格第一行的值來代替。怎么知道當(dāng)前列名的索引位置是多少呢?用List.PositionOf()來獲取。獲取到索引位置后,就很簡(jiǎn)單了,用Table{0}{索引位置}就可以得到列名對(duì)應(yīng)的第一行的值。

完成。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 總結(jié)了一些開發(fā)中常用的函數(shù): usleep() //函數(shù)延遲代碼執(zhí)行若干微秒。 unpack() //函數(shù)從二進(jìn)制...
    ADL2022閱讀 546評(píng)論 0 3
  • PHP常用函數(shù)大全 usleep() 函數(shù)延遲代碼執(zhí)行若干微秒。 unpack() 函數(shù)從二進(jìn)制字符串對(duì)數(shù)據(jù)進(jìn)行解...
    上街買菜丶迷倒老太閱讀 1,504評(píng)論 0 20
  • HTML 5 HTML5概述 因特網(wǎng)上的信息是以網(wǎng)頁(yè)的形式展示給用戶的,因此網(wǎng)頁(yè)是網(wǎng)絡(luò)信息傳遞的載體。網(wǎng)頁(yè)文件是用...
    阿啊阿吖丁閱讀 4,955評(píng)論 0 0
  • php usleep() 函數(shù)延遲代碼執(zhí)行若干微秒。 unpack() 函數(shù)從二進(jìn)制字符串對(duì)數(shù)據(jù)進(jìn)行解包。 uni...
    思?jí)鬚HP閱讀 2,135評(píng)論 1 24
  • 三月杭州之行,閨蜜讓給帶藕粉回來,順便也給自己帶了一盒, 大概是很久沒有吃上這好東西了. 帶回來的這一盒吃...
    自由行走的卡兒媽閱讀 283評(píng)論 2 0

友情鏈接更多精彩內(nèi)容