需求
有下面这样的表,如果同一行中有重复的数字,则标记“相同”;如果没有重复的数字,则标记“ok”。
列1 | 列2 | 列3 | 列4 |
---|---|---|---|
1 | 2 | 2 | 3 |
1 | 1 | 1 | 2 |
1 | 2 | 3 | 4 |
最终实现的效果类似如下:
列1 | 列2 | 列3 | 列4 | 自定义 |
---|---|---|---|---|
1 | 2 | 2 | 3 | 相同 |
1 | 1 | 1 | 2 | 相同 |
1 | 2 | 3 | 4 | OK |
分析
在PowerQuery中,要获取整列内容,可以用【[列名]】来获取。
要获取整行内容,可以用【table{行号}】来获取,行号可以通过添加索引列来获取。
在这个例子中,我们需要获取整行内容。所以应该用【table{索引}】。
由于要为每一行判定是否有重复值,所以【table{索引}】中的【索引】是动态的,那么通过添加一个自定义列就能实现。
【table{索引}】得到的结果是一个record类型,但我们不需要fields,只需要values,因此,可以用【Record.FieldValues()】来获取值列表。
需要注意的是,我们前面添加了【索引】列,【Record.FieldValues()】获取的list中也包含索引列的值,这是不应该的,应剔除。因此,我们要用【Record.RemoveFields(record,”索引”)】来剔除【索引】列。
那么如何判定一行是否有重复值呢?PowerQuery中有个【List.Distinct()】可以去除list中的重复值,我们把每一行的list去重后,将其长度与原来的list长度相比较:如果不符,则表示有重复项,标记为“相同”;如果两者长度相符,这意味着没有重复项,标记为“ok”。
代码
最后的完整代码如下:
let
源 = Excel.CurrentWorkbook(){[Name="表1"]}[Content],
已添加索引 = Table.AddIndexColumn(源, "索引", 0, 1),
已添加自定义 = Table.AddColumn(已添加索引, "自定义", each
if
List.Count(Record.FieldValues(Record.RemoveFields(已添加索引{[索引]},"索引")))=List.Count(List.Distinct(Record.FieldValues(Record.RemoveFields(已添加索引{[索引]},"索引"))))
then
"OK"
else
"相同"
),
删除的列 = Table.RemoveColumns(已添加自定义,{"索引"})
in
删除的列
延伸思考
这种方式的好处有两个:
一是无论每一行有多少列,都能处理。
如果用Excel公式的话,很难将单元格引用动态化。
比如这个例子,用Excel公式很简单:
=IF(SUMPRODUCT(COUNTIF(A1:D1,A1:D1))>COUNTA(A1:D1),"相同","OK")
但时只能处理四列数据,如果有更多列数得更改公式。
二是可以很轻松地应对基于此需求的别的需求,如,找出每一行重复的字符是什么,有多少个,可以很轻松地实现。
计算字符重复多少次:
= Table.AddColumn(已添加自定义, "重复次数", each
if List.Count(Record.FieldValues(Record.RemoveFields(已添加索引{[索引]},"索引")))-
List.Count(List.Distinct(Record.FieldValues(Record.RemoveFields(已添加索引{[索引]},"索引"))))=0
then 0
else
List.Count(Record.FieldValues(Record.RemoveFields(已添加索引{[索引]},"索引")))-
List.Count(List.Distinct(Record.FieldValues(Record.RemoveFields(已添加索引{[索引]},"索引"))))+1)
结果为:
寻找重复出现的字符:
已添加自定义2 = Table.AddColumn(已添加自定义1, "原始list", each Record.FieldValues(Record.RemoveFields(已添加索引{[索引]},"索引"))),
已添加自定义3 = Table.AddColumn(已添加自定义2, "去重后的list", each List.Distinct(Record.FieldValues(Record.RemoveFields(已添加索引{[索引]},"索引")))),
已添加自定义4 = Table.AddColumn(已添加自定义3, "包含重复字符的list", each List.Difference([原始list],[去重后的list])),
提取值 = Table.TransformColumns(已添加自定义4, {"包含重复字符的list", each Text.Combine(List.Transform(_, Text.From), ","), type text})
结果如下: