PQ-综合实战:格式化表单转数据明细之3:可配置的映射关系,你的数据你做主
【本文内容需要前期基础知识准备较为充分,但是,当你充分理解并完成了本文的内容,这将变成一个通用的可配置的格式化表单数据转换工具,以后只需要根据实际表单的格式情况,做好映射表的配置,即可实现相应表单数据的转换,一劳永逸。】
小勤:搞定了《Excel列表转成数字》,咱们开始格式化表单的可配置转换汇总吧?
大海:嗯。这个问题搞定了,就可以开始做数据的转换了。
小勤:但是有个问题啊,比如构造出来行标和列标了,但通过表里转换的列标是文本,在PQ里用跨表引用数据的方式好像不行呢。
大海:嗯。用列标名称引用的话,需要用个函数。首先,我们回顾一下《多个格式表单批量转换汇总》里的代码:
其中用红框框出来的内容是咱们修改的自定义函数,固定了列名和引用的位置,用红色荧光笔画出来的内容是在操作展开数据或删除其他列时自动生成的固定列名(为方便截图,对该部分代码做了换行处理),这些地方咱们要改成直接引用配置表的内容,从而实现随着配置表的改变而改变。
小勤:嗯。荧光笔画出来那部分改起来很容易,只要变成配置表里的内容列就好了。
大海:对的。所以首先改动这部分,改完后如下:
小勤:嗯。但上面那个自定义函数怎么改成引用配置表的就不懂了。
大海:这个我先把改好的给你,然后再跟你解析:
这个在自定义函数里面还是将要提取数据的表作为参数(s)传进去,构建table的列名由原来的固定内容改为从配置(映射表)里取,所以改为:映射表[内容],对应代码中的这部分:
接下来是通过“映射表[内容]”去找到每个表中要提取的数据。
针对每一个表,我们首先找到要提取的数据所在的行,然后在那一行里按照列名去取相应的内容,比如我们要提取“VIP登记表_1”中的“年龄”,定位过程如下:
1、通过映射表“内容”为“年龄”找到源表的索引(1)和源表列名(Column4),代码分别为:
取索引:映射表{[内容="年龄"]}[源表索引],结果为1
取列名:映射表{[内容="年龄"]}[源表列名],结果为"Column4"
2、根据源表索引(1)提取数据表中的第2行内容为一个记录(Record),对应的代码为:s{1},合并上面取索引的代码即为:s{映射表{[内容="年龄"]}[源表索引]}
3、根据源表列名(Column4)使用函数Record.Field从记录中提取数值(100),合并上面的代码为:
Record.Field(
s{映射表{[内容="年龄"]}[源表索引]},
映射表{[内容="年龄"]}[源表列名]
)
以上的说明中仅对“年龄”的具体内容进行了说明,为了取得所有的内容,通过对映射表[内容]使用List.Transform函数(关于该函数的使用,将在后续文章中专门说明,敬请关注),并将“年龄”改为下划线(表示针对映射表[内容]的每一个值提取相应的数据),主要代码如下图红框所示(最后括号未被包含):
最后,用大括号将提取的数据包裹起来,成为构造table的最终数据即可。
小勤:总的思路基本了解,但动手改这个代码感觉挺吃力的。
大海:对的,其中需要对《跨查询引用》和《根据内容定位》的知识需要理解得比较透,所以为什么我在前期关于“理解PQ里的数据结构”部分反复强调其重要性。
小勤:嗯。借这个案例我也可以再加深一下理解。另外,还要用到Record.Field和List.Transform两个函数,感觉就更复杂了。
大海:Record.Field函数其实很简单,2个参数:
第一个就是给它一条记录(Record),其实就是一个表的一行内容;
第二个参数就是告诉它类名,这样它就从给它的记录中返回相应列的内容。
小勤:嗯。这个还好。但List.Tranform感觉比较难。
大海:所以后面我会专门就这个函数举例子讲解,然后你再回头看这个,应该就不难了。
小勤:好的。