動態篩選

EXCEL 2010-2013 有個Power Query插件,需另外下載安裝,功能強大。可以從很多數據源提取數據關聯分析。EXCEL2016不需要安裝插件,功能直接合并到EXCEL數據菜單里面了。雖然也是不少個新東西,但國內用它的人還真不多,相關的教材案例就更少了。看到國外這篇博客,非常有啟發,特此抄過來供參考。

原文鏈接

以下為原文抄錄整理:

Have you ever had a user run a query against one of your largest tables only for them to immediately filter the results in Excel to show the last years worth of data? All of that data brought across your network and then immediately filtered out. Or maybe Excel just can handle the amount of unfiltered data they’re trying to return.

In this post I’d like to show you a way to solve this problem with Power Query in a solution that can dynamically filter your data returned based on user driven parameters.

In the scenario that I will demonstrate, rather then returning an entire result of all the company’s employees, I just want to return a list that show employees with a hire date within a certain range of dates that I or a user will provide. Using Power Query’s ability to make queries into Functions I’ll give my user the ability to provide the range of their choice

Connect to the Data

In my example I’m going use a SQL Server table as my data source but it could be any type of table. To connect to a SQL Server table from the Power Query tab in Excel select From Database > From SQL Server Database. For my example I’ll be using the AdventureWorksDW sample database.

Next you will be prompted to provide your Server and Database names where the table is located. Type these in then click OK.

Once you provide the Server and Database name you will also be prompted for the credentials you will use to access the data then click Connect.

The Navigator pane will appear showing all the available tables. If you’re following my example with the AdventureWorksDW sample database then choose DimEmployee and then click Edit. This returns back the table to the Power Query Editor. Note This could be done on any table from any database.

Making the Query a Function

What I’d like to have my users do is return back this list of employees but only when the HireDate column falls within a range of values that they provide. To do this we’ll start by applying a hardcoded value to filter to the HireDate column. Find the HireDate column and apply a filter by clicking the down arrow next to the column and then Date Filters > Between

The range of values you filter on will depend on your table but for the DimEmployee table in AdventureWorksDW I used the following filter then clicked OK.

This simple places a filter on the query. If we want to make the filter dynamic we need to modify the M Query that’s behind the user interface. Go to the View tab on the Query Editor ribbon and select Advanced Editor. This will open the query window where you can modify

Next modify this query to add in a start date and end date parameter with the code in red below.

<p style= "color:red" >
(startdate, enddate)=>

let Source = Sql.Database("localhost", "AdventureWorksDW2012"), dbo_DimEmployee = Source{[Schema="dbo",Item="DimEmployee"]}[Data], #"Filtered Rows" = Table.SelectRows(dbo_DimEmployee, each [HireDate] >= #date(2000, 1, 1) and [HireDate] <= #date(2002, 1, 1)) in #"Filtered Rows"

Once the parameters are created you can reference them in the query to replace the hardcoded value in the filter with a dynamic value from the parameters. Modify the query with the code in red below then click Done.

(startdate, enddate)=>
let Source = Sql.Database("localhost", "AdventureWorksDW2012"), dbo_DimEmployee = Source{[Schema="dbo",Item="DimEmployee"]}[Data], #"Filtered Rows" = Table.SelectRows(dbo_DimEmployee, each [HireDate] >= #date(Date.Year(startdate), Date.Month(startdate), Date.Day(startdate)
) and [HireDate] <= #date(Date.Year(enddate), Date.Month(enddate), Date.Day(enddate)
)) in #"Filtered Rows"

This will convert the query into a function. You can test this function by clicking Invoke and then you will be prompted to provide date values to filter on.

If you did invoke the function make sure you remove the Invoke step before moving on. You can do this by clicking the delete icon in the Applied Steps pane.

This should return the query back to a function ready to be invoked. Now, go to the Home tab on the Query Editor ribbon and select Close & Load.
This will save the M Query function into the workbook but does not return any results yet. Just how we want it! Our next step is to pass the values we want into the function.

Making it User Interactive

Go to a blank spreadsheet and create a simple Excel table that has a StartDate and Endate column with one row of values like this:

To make it so our users can type a value in this Excel Table and pass it into our function we need to take bring this small table into Power Query. Select one of the cells inside the table and on the Power Query tab select From Table. This will take the content of this table and bring it into the Power Query Editor.

To pass these two values into our function go to the Add Column tab and select Add Custom Column.
Write the following formula to connect the DimEmployee function created earlier to the dates we’ve now defined in the Excel table then click OK:

DimEmployee([StartDate],[EndDate])

If all your default settings are turned on inside Power Query you will probably get a privacy warning pop up. This is because you’re working with two different data sources (1. SQL Server Table, 2. Excel Table) and there’s potential privacy concerns. In our scenario there are no legitimate privacy concerns so I’ll hit Continue. I also set the data sources to Organizational because the data sources should be contained within my company. Read more about Power Query privacy settings here.

Once the privacy settings are configured Power Query will add in a new column just called Custom (We could have renamed it previously). Click the Expand button next to the Custom column, uncheck Use original column name as prefix and then click OK. This will bring back all the rows that have hire dates between our date range.

Go ahead and remove the StartDate and EndDate columns from the query now but multi-selecting them and then right-click and select Remove Columns.

Next, rename the query in the Query Settings pane to Employee Data then click Close & Load on the Home tab.

You should now have two spreadsheets (It would obviously be a good idea to rename these) in your workbook.
Sheet1 that has the Excel table with the date range values
Sheet2 that has the results of the Power Query query. This data could have optionally been send to the Power Pivot Data Model

Now go back to Sheet1 and change the date range values in the StartDate and/or EndDate columns. After making this change the next time the Power Query query is refreshed it will pick up the results from the table to filter on saving your users from query a really large table when they only need a subset of the data.

Finishing Touches

If my users aren’t very familiar with Power Query and don’t know how to refresh their queries then we can build a quick little macro to provide a button that does it for them. Using a technique I learned from Ken Puls (blog | twitter) in a few short steps our macro will be done. In Ken’s post titled Refresh Power Query with VBA he shows how to refresh all Power Query queries in a workbook with a little VBA script. I’m going to take the same principles he shows but just refresh the query I care about.

In your workbook press Alt + F11
Right-click on VBAProject(Book1), this may be named something different if you’ve saved with a new name, in the Project Explorer and select Insert > Module.

Use the following VBA script to refresh the workbook connection for our Employee query we created earlier (If you named your query something different you may need to adjust the section highlighted in red):

Public Sub UpdateEmployeeQuery() ‘ Macro to update my Power Query script(s)
Dim cn As WorkbookConnection
For Each cn In ThisWorkbook.Connections 
   If cn = "Power Query – Employee" Then  cn.Refresh 
Next cn 
End Sub

Hit close on the VBA window.
To manually try the new code hit Alt + F8 and you will be prompted to run the script. Select the Macro we just created and click Run.

You should notice this kicks off the refresh of our Employee query.

To turn this into a button go to the Developer tab. Instruction on how to make the Developer tab visible. https://support.office.com/en-nz/article/Show-the-Developer-tab-e1192344-5e56-4d45-931b-e5fd9bea2d45
Select Insert > Button

Click somewhere in the worksheet that you want the button and then select the Macro we created to assign to the button. Click OK.

Click inside the button to rename it and then you’re all set!
Now all you have to do is change the values in the table and click the button to refresh the results of the query. This works if the results are rendered to an Excel spreadsheet or Power Pivot Data Model.

As long as the data source and types of transforms support it Query Folding will still be utilized with this method. If you’re curious about what Query folding is read more about it in this Matt Masson post.
I’ve made this example available if you would like to download it: User Driven Parameter Example.xlsx

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,646評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,595評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,560評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,035評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,814評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,224評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,301評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,444評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,988評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,804評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,998評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,544評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,237評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,665評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,927評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,706評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,993評論 2 374

推薦閱讀更多精彩內容