Excel之PowerQuery 从课程表了解教师任课情况
网友提问,有如下一张课程表

需要从课程表中了解到每位教师都任教于哪些班,哪些课。

一、友情提示:提问中最忌讳的事情
1、数据量大:这种情况做完后无法检查对错,手工复核太麻烦,尽可能缩小表格行列数。做到肉眼可见对错。
2、目标表数据错误:因为业务是您自己的,别人能帮您解决计算机的问题,业务问题您不应该抛给别人。您提供原数据表和目标表,那目标表是应该经您手工复核的,现在目标表的结果是错误的,可能您的意思是说就想要这么一个表,今天这个事我略懂,因为都上过学,如果您所从事的行业需要指定专业,且非常识性问题,我将爱莫能助。
3、即便是常识问题,具体接触工作的人也会更了解自己的需求,例如这个问题,谁是主科,谁是副科,数语英肯定是主科,那音乐、体育怎么算?是与劳动、社团、自习算到一起,还是与数语英算到一起?这些都没有说清楚。我们不是商人与消费者的关系,我不可能花大量时间与每个人核对需求。
4、此问题不涉及一位教师讲多门主课的情况,例如数学老师同时教语文,目前只有培训机构有这种情况,正规学校教师大多是一人一科,只是稍带一些社团、自习之类的。我们暂时忽略一个人又教数学又教语文的情况,且默认班会、社团等全校在同一时间进行。
如果需求进一步升级,那具体问题具体分析。
二、修改表格让小学生听懂我想做什么
提问一定要让小学生听懂,小学生可以不会做,但是一定要听懂我在说什么,反之如果小学生听不懂你在说什么就是你暂时对业务不理解。例如:曾经有位皇帝,他想长生不老,皇帝的表达能力没问题,可以没有长生不老药,但是我们必须要知道自己想做什么,做不出来不可怕,可怕的是不知道怎么表达自己的需求。
现在我们要将这张表:

变成:

三、开始数据清洗
如果这个案例不分主副科,不用按年级班级排序,点几下鼠标一行代码就搞定了,但是现在加上了这些需求,代码量就大起来了。
1、导入表格到PowerQuery中

2、选中科目列~转换~逆透视~逆透视其它列
二维表是打印或观赏的,我们先将它转成一维数据表

我将其改成如下列名:

3、处理主副科和年级班级排序问题
从提问者的目标表上,我们可以推断出,排序规则是:一(1),(2)... 二(1)(2)... 三(1)(2) 且主科与副科分开。

【1】添加列,判断主副科

【2】搞定排序、年级、班级
(1)添加列,提取年级(汉字)

(2)添加列,提取带括号的班级

(3)添加列,做排序列

【3】开始套娃
1、按教师姓名分组,第一个组写课程,第二个组计算课时
课时计算每个人子表的行数就可以了。

2、大娃是任课情况,我们处理它


现在关系图是这样的:最左边表的每个Table是大娃,中间三张表的每个Table是中娃

我们只需要分析其中任意一组即可:

对中娃按年级分组

修改后的代码如下:
现在中娃到小娃的关系如下:

我们发现,只需要小娃绿圈中的数据拼成字符串即可,有些小娃会牵扯一个排序问题

修改后的代码:

Text.Combine(List.Distinct(Table.Sort(小娃,"排序")[年级])) & Text.Combine(Table.Sort(小娃,"排序")[班],"、") & Text.Combine(List.Distinct(Table.Sort(小娃,"排序")[科目]),"、")
相当于: 一 & (1)、(2) & 数学 = 一(1)、(2)数学

现在我们将小娃变成了这个样子:

现在只需要取中娃的【数据3】这个列,所以Table变List

再取大娃的【数据1】列,Table又变List

使用List.Combine将大娃中的列表合并

最后使用Text.Combine对每个大娃中的List转成Text文件用逗号隔开

上载后的结果:

我们发现了一个小问题,问题的原因在于我们没有对带括号的班级列表去重

我们修改一下:
Text.Combine(List.Distinct(Table.Sort(小娃,"排序")[年级])) & Text.Combine(List.Distinct(Table.Sort(小娃,"排序")[班]),"、") & Text.Combine(List.Distinct(Table.Sort(小娃,"排序")[科目]),"、")
现在把这段话替换之前的代码
最终代码如下:

最终上载后的结果:


PowerQuery合集:https://www.bilibili.com/video/BV1oa4y1j75e