动态筛选

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阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容