從今天開始,我們將逐漸引入一些術語,以便為達到我們的最終目標做好準備。
此前,我們通過Power Query導入了文件/文件夾中的數據,並做了初步整理和篩選,但是在這一過程中我們並沒有操作過原來的文件/文件夾,甚至沒有打開過它;我們只是查找到了原來的數據內容,將我們想要的數據顯示在了屏幕上,加載到了一個新的Excel文件中。在這一過程中,數據文件本身沒有被更改。
正式的,我們把這種通過某種方式(比如Power Query)查找並選取出所需數據的過程稱作「查詢(Query)」。今後,我們將不再使用「導入數據」或「數據導入過程」之類的說法,而正式的將其稱為「查詢(Query)」。
查詢設置
在最初的例子中,我們建立了一個針對Sample1文件數據的查詢,並保存了它。讓我們重新打開這個查詢。本節將重點關注Power Query編輯器右側的面板,即「查詢設置」。
查詢設置的第一部分是「查詢屬性」,在這裡只有一個重要屬性,即本查詢的名稱。在默認情況下,Power Query編輯器會使用工作表名、文件名或文件夾名對查詢進行命名,但將其更改為有意義的名稱是一個優秀的編程習慣,哦不,請忽略剛才那句話中「編程」兩個字。
重命名查詢後能讓我們更好的辨識它,為日後或共享給他人使用提供便利。我們可以將其命名為「單家商店庫存查詢」——直接在名稱框里輸入新名稱並回車確認就可以了。
查詢設置中「應用的步驟」才是今天的重點,它保存了我們從找到數據源文件到選取數據、整理數據的全過程,也就是Power Query的查詢步驟。每次我們運行查詢時,實際上就是按該步驟的順序對數據進行操作。今天的工作是通過解讀這些步驟,了解到Power Query是如何一步一步的將原來的數據變成我們想要的樣子的。讓我們開始吧。
找到數據文件:源
查詢的第一步一般都是是「源」,即找到數據文件,點擊步驟「源」(標記①),我們可以看在Power Query編輯器中看到一些熟悉的身影:首先,在數據區域中出現了兩列(標記②),分別代表了工作表名和工作表數據(不要忘了數據本身是一個「實體」,該實體也可以作為一個數據出現在單元格中);點擊代表工作表數據的單元格,可以在預覽區(標記③)看到數據的實際內容;在編輯欄中,我們又看到了熟悉的Excel.Workbook()函數(標記④),它的作用就是打開指定文件的內容,不過這裡的「指定文件」不在被裝在「Content」列中,而是使用另一個函數,連接到該文件的路徑進行打開。
請注意「源」步驟的右側存在一個小齒輪,該齒輪表示我們可以修改該步驟的參數。點擊該小齒輪,彈出了一個類似「修改數據源」的窗格,其功能與之前我們提到過的在Excel的數據選項卡下修改數據源的作用一致:修改該參數將修改本查詢的數據文件地址。
事實上,通過該窗格修改參數本質上就是修改編輯欄中Excel.Workbook()函數中的地址部分。在某些情況下,「源」步驟右側的小齒輪會消失(這可能是Power Query的一個Bug),我們不能通過彈出窗格修改該步驟的參數,也不能在Excel的數據選項卡下修改數據源地址,但我們可以直接在編輯欄中修改該公式的參數。
找到指定的工作表:導航
我們通過第一步找到文件後,查詢的第二步當然是找到該文件中的某個工作表,在這裡叫做「導航」。該步驟找到了我們想要的工作表,並展開該工作表的數據。通過運行查詢的第二步,我們已經查找了我們需要的數據,但我們看到的是數據原始模樣:存在大量空行、各列也沒有按我們的期望排序、部分列並沒有進行類型識別、甚至第一列還沒有被識別成為標題。
請注意,「導航」步驟右側也有一個小齒輪,很容易想到它的作用是設置我們到底要找那個工作表,修改該設置的實際作用其實也是修改編輯欄中函數中對應的工作表名參數。
對原始數據進行整理:提升標題、更改類型等
通過運行前兩步,我們找到了原始數據,但我們需要對該原始數據進行進一步整理。
首先是將首行提升為列名,或者說標題,這一步Power Query已經自動幫我們做了,叫做「提升的標題」……,一看這就是劣質的機器翻譯,為了保持我們優秀的命名習慣,將這一步重命名為一個有意義的名稱,比如「將首行提升為標題」
其次,此前Power Query已經幫我們對各列進行了自動類型識別,但正如我們前面提到的,不要相信自動類型識別,全部重新檢查一遍並按需修改。請注意,當我們進行類型更改時,Power Query可能會提醒我們「是否插入步驟」,請先選擇「是」;「替換步驟還是添加新步驟」,請先選擇「替換步驟」。
請注意,這裡我們對自動生成的步驟進行了修改。
另外,我們還對行進行了篩選、對列進行了重新排序,這些操作都被Power Query保存成為了查詢步驟,我們可以逐一點擊這些步驟,檢查這些步驟是否就是當時我們操作。
最後,讓我們把這些步驟都改成有意義且易於理解的名字。
對查詢步驟的重新排序
雖然Power Query能夠自動生成步驟,但這些步驟是可以更改的。比如我們增加的兩個步驟(刪除空行、重新排列)、對自動生成的步驟進行了修改(在自動識別類型的基礎上進行了手動更改)。但其實我們還可以進行一些其他操作。
例如,本查詢中的最後三個步驟「更改數據類型」、「篩選有效行」和「對列進行重新排序」其實相互獨立,如果更改他們的順序不會對查詢結果造成影響。
但是,如果我們將「將首行提升為標題」的順序進行移動,則極有可能出現問題。
這時因為「更改數據類型」、「篩選有效行」和「對列進行重新排序」本質上都是通過列標題對各列的數據類型、篩選情況和順序進行更改。例如,篩選有效行實際上是篩選出「商品名稱」列不為null和""的且「庫存數量」不等於0的行:
這是一個哲學問題:對列標題進行操作的前提的是存在相應的列標題(「商品名稱」、「庫存數量」)。而實際上本查詢的列標題是通過「將首行提升為標題」這一步驟產生的,所以必須把產生列標題(確切的說是命名列標題)這一步驟放在所有需要對列標題進行操作的步驟前面,列標題才能被找到、被操作。
更加概括性的說,如果某些步驟對其前序步驟(某中間步驟)存在依存關係,那麼更改被依存的步驟就極有可能讓該後續依存步驟出現問題,進而使整個查詢出現問題。
刪除查詢步驟
相信讀者已經注意到了,每個步驟前面都有一個小×號,表示我們可以刪除該步驟。如果過刪除了某一步驟,我們就少了一部分工作。與修改步驟類似,刪除被依存的步驟也極有可導致查詢出錯。
新增和插入步驟
之前我們通過操作Power Query增加了「篩選有效行」和「對列進行重新排序」兩個步驟,實際上您沒有注意到,我們都是在選中當時查詢的最後一步時操作的,這樣的操作為我們在查詢的末尾新增了步驟;但是,如果我們選中查詢的中間步驟進行操作時,結果就會是在選中步驟的後面「插入」步驟而非在最後新增步驟。插入步驟如果更改了被後續步驟依存的部分,同樣可能導致後續查詢出錯,之前我們在選中「更改數據類型」進行操作時,已經接到提示了。
對查詢步驟的一個建議
既然在在如此多的情況下都可能出現因依存關係導致查詢出錯的情況,那麼我強烈建議,除非讀者能夠理解每個步驟的原理,並能理清各步驟間的依存關係,那麼應該盡量避免在一個查詢的中間插入、修改或刪除步驟。相反,我們應該通過在查詢的末尾新增步驟的方式達到我們進一步整理數據的需求。
如果某個操作在此前的步驟中沒有處理完全,我們也可以新增一個步驟來繼續處理它而不是採用之前使用的「替換步驟」操作。Power Query並不要求將所有相同功能的操作放在同一步驟中,也不要求這些步驟一定要連續排放。
同樣,如果我們發現整理數據時出現了一些錯誤,我們可以將查詢出錯的後面幾步刪除,直至我們需要保留的步驟,再進行重新整理。當然,我們也可以使用「刪除到末尾」刪除某步驟及其後續所有步驟