小勤:大海,现在有一堆格式化的表单,像这样的:
怎么转成下面这样规范的数据明细啊?不然没法做数据分析呢。
大海:这种填报格式的申请表、登记表等等的要转为规范的数据明细还真是经常有的事。以前我写过一个可配置的VBA,就是自己定义好哪个单元格的内容转到明细表里的哪一列,比如配置表:
然后运行程序,选择需要的文件统一导入到一个文件中:
小勤:这种可配置的导入程序很好啊!就像要这样的效果!
大海:不过,以前得用VBA的这个事情,现在其实可以用Power Query来实现了。
小勤:啊!那太好了。怎么做呢?
大海:其实思路差不多,就是先找到源数据表(格式表)需要导入的数据与目标表(规范明细表)的关系,然后把源表的数据放到目标表里。咱们先从这个简单的例子开始,今天先实现一个表格的转换,后面咱们在逐渐扩展到多表的、映射关系可配置的方式。
Step-01:从工作簿获取数据到PQ
Step-02:为避免数据类型转换错误,删掉PQ自动添加的“更改的类型”步骤
结果如下:
显然,其中有很多合并单元格的内容被识别成了null,这些我们都可以不管它,只要知道需要提取的信息固定在什么位置就好了,比如姓名“大海”在“Column2”的第“2”行(索引为1),所以,参考《理解PQ里的数据结构(二、行列引用)》的方法,只要读取这个表里的{1}[Column2]就可以得到姓名……
汇总对应关系如下表所示:
Step-03:修改生成的代码以完成转换
原来的代码是这样的(这里“源”行代码可能与您实际操作内容不同,因为已经修改了工作簿动态接入路径,与本文主体操作内容无关,若希望了解该内容,请参考《结合CELL函数实现数据源的动态化》):
修改后代码如下:
其中主要修改内容如下:
1、改个名称:原代码中生成的名称太长,为后面写起来方便,将“VIP登记表_Sheet”修改为“s”(这种修改经常用);
2、构造新的表(table):增加图中蓝色背景代码
代码语言:javascript复制 d = #table(
{"姓名","年龄","性别","公众号","兴趣","电话","邮箱"},
{{s[Column2]{1},s[Column4]{1},s[Column6]{1},s[Column2]{2},
s[Column4]{2},s[Column6]{2},s[Column2]{3}}}
)
这句代码的含义就是直接用关键字#table构造表,语法很简单,就是先给标题名称列表,然后再给各行数据列表组成的一个列表(列表嵌套),具体语法如下:
代码语言:javascript复制#table({标题},
{{第1行数据},
{第2行数据},
…})
再简化一点儿用具体数据举个小栗子:
代码语言:javascript复制#table( {"姓名","年龄"},
{{"大海","100"},
{"小勤","18"}} )
就会得到以下内容的表:
小勤:理解了,这样标题和内容都明显意义对应的啊。看起来真是不难嘢,比写VBA好多了。呵呵
大海:嗯。当然啦,如果用VBA做的话,可以做得更加灵活,只是学VBA所需要投入的精力要更加大而已。