今天我講的這個案例的場景是:我在Excel表格里保存了一些列信息,如下左圖所示。這些列將會在我的程序中用於自動生成文件。我們都知道能作為文件名的字符是有限制的,Windows中不予許在文件名出現部分字符,這些字符如下右圖所示。
![]() |
![]() |
為了防止我的程序在運行過程中不會因為文件名混入以上的非法字符而中途退出,我需要預先處理那些我需要作為文件名的列。我的文件名的命名格式如下:
ID-省市自治區-城市-公司
將我們的目標用一句話來描述:
將表中省市自治區,城市和公司列中所有單元格中的非文件名字符清理掉
操作步驟如下:
- 首先將數據導入到PowerQuery中,該步驟很簡單,不再給出圖片演示,不清楚的話,可查閱我之前的實例;
- 我在PowerQuery中將這個導入的表命名為Data,如下圖;
- 選擇“關閉並上載/關閉並上載至/僅創建鏈接”,退出PowerQuery編輯器,回到Excel界面,在Excel中輸入非法文件名字符集列表:
- 類似第1步,將非法文件名字符導入到PowerQuery中,並將該列表命名為“SearchList”
-
接下來我們需要將SearchList轉換為List,這是因為后面我們需要使用List的遍歷函數來遍歷其中所有的項,操作很簡單,只需要右擊標題單元格,選擇“深化”即可
- 為了在PowerQuery保留以上已經導入的數據,我在PowerQuery中新建一個空白查詢,來做后續的處理。在左側導航窗格的空白區域右擊,依次找到空白查詢項
- 接下來的思路是:遍歷列表SearchList中的所有項,依次清理Data表中所有想要處理的列。這里實際會有2層遍歷,外面一層是遍歷列表項,里面一層是遍歷所有的列。我們首先考慮最外面一層。對列表項進行遍歷,需要使用到函數List.Accumulate,下圖是官方對該函數的解釋。
-
照着List.Accumulate函數的格式,在空查詢中輸入如下所示的內容,以下內容還未寫完,請不要輸入回車檢查運算結果!
= List.Accumulate(SearchList,Data,(t,i)=> )
(t,i)=>符號后面我留了空,因為后面的部分是要對表進行處理,是后續步驟的內容。我們先理清當前這個函數的含義:
第一個參數是SearchList:函數將遍歷SearchList所有的項
第二個參數是Data:這是函數最初進行處理的表,意即函數遍歷SearchList每一項,首先在處理SearchList的第一項時,是針對Data這個表進行操作,操作完畢后我們得到Data表被處理后的表Data1(內存中);接下來處理SearchList的第二項,它針對的是Data1表,處理完畢后Data1變化為Data2;然后處理SearchList的第三項,其針對的是Data2,處理完畢后Data2變化為Data3;依次類推,直到最后處理完畢SearchList中的所有項,我們就將最初的Data表進行了對應次數的變換處理,得到最終處理完畢的Data表。
第三個參數是一個函數:它告訴List.Accumulate函數,在每一次使用SearchList中某一項操作Data表時,其操作的方式是如何的。因而這個函數工作的時候,必須知道當前的SearchList項是什么,以及Data表。參數的順序是固定的,List的當前項current應該放在后面,狀態值也就是Data表要放前面,我的公式中使用t(table),i(item)標識這2個參數。
- 在以上List.Accumulate函數第三個參數的主體部分,我們需要對Data表的特定列進行替換值操作,需要用到Table.ReplaceValue函數,下圖是該函數的簡單介紹
第一個參數是表對象:此處就是當前的表對象
第二個參數是被替換的值:此處就是當前SearchList列表中需要處理的項i
第三個參數是替換后的值:我們是需要清除,所以就是變成空字符串””,2個引號間中間不要有空格!
第四個參數是一個函數:它告訴Table.ReplaceValue函數,替換操作使用哪種操作方式來替換,我們使用已有Replacer.ReplaceText即可
第五個參數是需要對表的哪些列進行操作:這個參數是一個字符串列表
最終我們書寫好的公式代碼如下:
= List.Accumulate(SearchList,Data,(t,i)=> Table.ReplaceValue(t,i,"",Replacer.ReplaceText,{"省/市/自治區","城市","公司"}))
最后處理的結果如下圖所示