此案例来源于雷友会QQ群(198086726)。源文件偷懒不给出了。
需求
单元格中的值由为长度不等的数字组成,要求求出每个单元格的所有数字之和,如下图:
比如,第一行的结果是6+2+2+5+7+5+7+6+7+6+3+4+2+1+2+7=72,以此类推。
分析
解决这个问题的思路是怎么把单元格的内容拆分为独立的数字,否则无法求和。
一旦涉及到拆分,我们首先想到的是分列,这就是群里“新云”给出的方法一【按位置分列版】。
不过我这两天在啃Python,里边提到文本操作时,可以用list()函数把单词拆分为由字母组成的list,如list(wanght)=['w','a','n','g','h','t']。我在群里瞄见这个例子后,突发奇想,PowerQuery会不会有类似功能的函数呢?打开函数参考,一个一个找,果然被我找到了Text.ToList()这个函数,它起的作用和Python中的list()一模一样。所以这就是方法二【Text2List版】。
按位置分列求和
let
源 = Excel.CurrentWorkbook(){[Name="表1"]}[Content],
复制的列 = Table.DuplicateColumn(源, "数字", "numbers"),
用位置分列 = Table.SplitColumn(复制的列,"numbers",Splitter.SplitTextByRepeatedLengths(1),{"数字 - 复制.1", "数字 - 复制.2", "数字 - 复制.3", "数字 - 复制.4", "数字 - 复制.5", "数字 - 复制.6", "数字 - 复制.7", "数字 - 复制.8", "数字 - 复制.9", "数字 - 复制.10", "数字 - 复制.11", "数字 - 复制.12", "数字 - 复制.13", "数字 - 复制.14", "数字 - 复制.15", "数字 - 复制.16", "数字 - 复制.17"}),
逆透视的其他列 = Table.UnpivotOtherColumns(用位置分列, {"数字"}, "属性", "值"),
更改的类型 = Table.TransformColumnTypes(逆透视的其他列,{{"值", Currency.Type}}),
分组的行 = Table.Group(更改的类型, {"数字"}, {{"求和", each List.Sum([值]), type number}})
in
分组的行
Text2List之后求和
let
源 = Excel.CurrentWorkbook(){[Name="表1"]}[Content],
复制的列 = Table.DuplicateColumn(源, "数字", "numbers"),
文本到List = Table.AddColumn(复制的列, "list", each Text.ToList([numbers])),
ListSum求和 = Table.AddColumn(文本到List, "求和", each List.Sum(List.Transform([list],each Number.From(_)))),
删除的列 = Table.RemoveColumns(ListSum求和,{"numbers", "list"})
in
删除的列
总结与反思
观察两个方法,发现都用了List.Sum()这个函数。所以,这个函数是处理这类求和问题的关键,就是把求和对象拆解为list,然后来求和。而得到一个list的方法是多种多样的。就我个人而言,更喜欢我自己找到的Text2List方法,因为这个只涉及Text.ToList()和List.Sum()这两个函数,而【按位置分列求和】涉及到复杂的分列、逆透视和分组操作。
这个例子还可以有多种变形,比如有些人喜欢把手机号码的各组成数字求和,或者把自己名字的拼音字母求和等。