【实例】用PowerQuery和PowerPivot统计班级信息

【需求】

这是一个小例子,需求很简单:
1.统计截止目前,所有我负责的班级数量和学员数量;
2.统计所有已经结束的班级的数量,以及应该结束但是尚未结束的班级数量;
3.统计本月开班的班级数量,并列出明细;
4.统计应在本月结束的班级数量;
5.两周汇报一次以上数据。


班级原始数据.png

【思路】

因为每两周就要汇报一次统计结果。因此我希望实现自动化——我只需要导出原始数据,然后打开报告,刷新,就获得最新结果。为了实现这个目标,我需要同时用到PowerQuery和PowerPivot。

PowerQuery的作用是引入数据源,并获取本月开班明细;PowerPivot的作用是借助DAX来计算并得出其他数据。

【步骤】

1.建立单独的项目文件夹
原始信息是从系统导出的数据,不作任何更改,也不重命名。如果没有单独的项目文件夹,由于系统导出的数据命名都是一样的,所以很容易就和其他导出的数据文件混淆了,除非我重命名——作为懒人来讲,重命名也很讨嫌啊。

因此我需要单独为此工作建立一个项目,我用文件夹的方式来统一管理原始数据和统计结果报表。

工程文件夹.png

为什么要单独建立一个“原始信息”文件夹呢?这是处女座强迫症——原始数据和结果数据混在一起总是让人纠结,是不?

2.导出原始数据,放入项目文件夹的子文件夹“原始信息”文件夹中,不作任何改动,也不重命名。系统中导出来的是什么样,就是什么样。

3.新建一个Excel文件,重命名为“班级统计结果”。

4.使用PowerQuery的参数表格建立参数表格及其函数。
如果只是我一个人用,其实参数表格没必要。但是我有个野心——想让其他同事拷贝我这个工程文件夹到ta电脑后,ta不需要做任何修改就可以直接使用模板。

参数表格建立方法见《PowerQuery的参数表格用法》。参数表格只有一个参数,其值是一个公式:

=LEFT(CELL("filename",A1),FIND("[",CELL("filename",A1),1)-1)&"原始信息\"

这个公式的目的就是为了让此工程文件能在别的电脑上无障碍使用,不用修改数据源的路径。

参数表格参数值.png

5.用PowerQuery对数据源进行引入和整理,代码如下:

let
源 = Folder.Files(fnGetParameter("班级汇总报表")),
删除的其他列 = Table.SelectColumns(源,{"Content"}),
合并的二进制 = Binary.Combine(删除的其他列[Content]),
#"导入的 CSV" = Csv.Document(合并的二进制,[Delimiter=",", Columns=14, Encoding=936, QuoteStyle=QuoteStyle.None]),
提升的标题 = Table.PromoteHeaders(#"导入的 CSV"),
更改的类型 = Table.TransformColumnTypes(提升的标题,{{"序号", Int64.Type}, {"班级名称", type text}, {"起止日期", type text}, {"所属域", type text}, {"承办单位", type text}, {"班级管理员", type text}, {"应到人数", Int64.Type}, {"实到人数", Int64.Type}, {"参加率", type text}, {"班级状态", type text}, {"整体满意度", Int64.Type}, {"预算费用", Int64.Type}, {"实际费用", Int64.Type}, {"", type text}}),
用分隔符分列 = Table.SplitColumn(更改的类型,"起止日期",Splitter.SplitTextByDelimiter("至", QuoteStyle.Csv),{"起止日期.1", "起止日期.2"}),
更改的类型1 = Table.TransformColumnTypes(用分隔符分列,{{"起止日期.1", type date}, {"起止日期.2", type date}}),
筛选的行 = Table.SelectRows(更改的类型1, each not Text.Contains([班级名称], "提报")),
重排序的列 = Table.ReorderColumns(筛选的行,{"序号", "班级名称", "实到人数", "起止日期.1", "起止日期.2", "所属域", "承办单位", "班级管理员", "应到人数", "参加率", "班级状态", "整体满意度", "预算费用", "实际费用", ""}),
删除的其他列1 = Table.SelectColumns(重排序的列,{"班级名称", "班级状态","实到人数", "起止日期.1", "起止日期.2"}),
重命名的列 = Table.RenameColumns(删除的其他列1,{{"起止日期.1", "线上学习开始日期"}, {"起止日期.2", "线上学习结束日期"}})
in
重命名的列

忽略多余的字段和代码格式吧。我也没有对每一个步骤进行有意义的命名。

注意“源=……”这一行,使用了参数表格函数引入数据源路径。
注意“用分隔符分列”这个步骤,这是因为原始数据的班级开班和结束日期是在同一个字段里,因此需要将其拆开为“开始日期”和“结束日期”两个字段。

6.将PowerQuery查询结果加载到数据模型,仅创建链接。

7.获取本月开班明细。
这里我是直接引用了前面创建好的查询,然后用公式筛选,代码如下:

let
  源 = 原始信息,
  筛选的行 = Table.SelectRows(源, each Date.IsInCurrentMonth([线上学习开始日期]))
in
  筛选的行

这里也可以用PowerQuery的Evaluate来创建查询,但是比较麻烦,还不如直接引用查询然后筛选。

将其加载到表,并重命名为“本月明细”。

注意用Date.IsInCurrentMonth()的目的也是为了偷懒,要不然可以直接筛选具体的月份来实现——但那样太麻烦,不是?

8.进入PowerPivot,创建需要的度量值:

总班级数=COUNTROWS('原始信息')
总参加学员数=SUM('原始信息'[实到人数])
已结束的班级=CALCULATE(COUNTROWS('原始信息'),FILTER('原始信息','原始信息'[班级状态]="已结束"))
本月=MONTH(NOW())
本月开始线上学习的班级数=CALCULATE(COUNTROWS('原始信息'),FILTER('原始信息',MONTH('原始信息'[线上学习开始日期])=[本月]))
本月参加学员数=CALCULATE(SUM('原始信息'[实到人数]),FILTER('原始信息',MONTH('原始信息'[线上学习开始日期])=[本月]))
本月应结束班级数=CALCULATE(COUNTROWS('原始信息'),FILTER('原始信息',MONTH('原始信息'[线上学习结束日期])=[本月]))
上月应结束班级数=CALCULATE(COUNTROWS('原始信息'),FILTER('原始信息',MONTH('原始信息'[线上学习结束日期])=[本月]-1))

9创建基于数据模型的数据透视表,将需要的字段拖入数据透视表,最后结果如下:

统计结果.png

很简陋的一个表,因为是内部使用,我就偷懒了。
公式和统计结果中,我塞入了一个“上月应结束班级数”,这个是个bonus,可以无视。

【共享方法】

将工程文件夹全部拷给需要的人,然后ta导出自己需要的班级数据,放到“原始信息”文件夹,打开统计结果文件,刷新,即可获取最新结果。

有个前提:最好是Excel 2016。如果是Excel 2013之类的老版本,确保PowerQuery和PowerPivot插件启用。

【反思】

其实最后建立度量值时,我可以不必那么麻烦,利用好切片器和筛选,可以获取到更动态的统计结果。但是考虑到不见得使用此报表的人员会使用这些复杂的数据透视表功能,所以我直接把对方想要的数据写死呈现出来。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,494评论 18 139
  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...
    数据革命阅读 12,112评论 2 34
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,050评论 25 707
  • 读国学经典的孩子做事情更有恒心。《论语》曰:“言必信,行必果。”任何一个事业的成功=选择+坚持+执行力。当孩子立志...
    双妈刘旭阅读 338评论 0 0
  • 11月开始整理资料,12月中旬才走完全部程序,可什么时候才能看到结果公布呢? 坊间已经开始有小道消息了,灵通人士说...
    山水白雲间阅读 242评论 0 0