Power Query双循环列表匹配问题:自定义函数传参错误排查
问题说明
我有一个包含TXT1、TXT2列的表格,列中文本以逗号分隔,且每列文本顺序不同。第一步我将文本拆分为列表,下一步编写了CheckMatch函数,用于检查第一个列表中的所有文本是否都存在于第二个列表中——若全部存在则返回"YES",否则返回"NO"。现在我想构建双循环,外层循环遍历TXT1中的所有列表,内层循环遍历TXT2中的所有列表,但因参数传递错误导致报错。
原代码
主查询代码
let TXT1 = {"RV0003,19915,26966", "RVG002,19923,26966", "NO", "NO", "NO"}, TXT2 = {"NO", "NO", "RV0002,19915,19923,26966", "RV0003,19915,19923,26966", "RVG002,19915,19923,26966"}, TableFromColumns = Table.FromColumns({TXT1, TXT2}, {"TXT1", "TXT2"}), Step_Split_TXT1 = Table.AddColumn(TableFromColumns, "Split_TXT1", each Text.Split([TXT1], ",")), Step_Split_TXT2 = Table.AddColumn(Step_Split_TXT1, "Split_TXT2", each Text.Split([TXT2], ",")), AddIndex = Table.AddIndexColumn(Step_Split_TXT2, "Index", 0, 1), AddMatchResult = Table.AddColumn(AddIndex, "MatchResult", each List.Accumulate([Split_TXT2], "NO", (state, current) => if state = "YES" then "YES" else CheckMatch([Split_TXT1]{[Index]}, current))) in AddMatchResult
自定义函数CheckMatch
let CheckMatch = (list1 as list, list2 as list) => let Difference = List.Difference(list1, list2), MatchResult = if List.IsEmpty(Difference) then "YES" else "NO" in MatchResult in CheckMatch
错误原因分析
- 参数类型不匹配:在
List.Accumulate中调用CheckMatch时,传入的第二个参数current是Split_TXT2列表中的单个元素(如"NO"或编号字符串),但CheckMatch要求第二个参数是完整列表,直接导致类型错误。 - 逻辑偏离需求:原代码遍历的是当前行
Split_TXT2的单个元素,而非所有行的Split_TXT2完整列表,没有实现“外层遍历TXT1所有列表、内层遍历TXT2所有列表”的逻辑。
修正方案
要实现目标逻辑,需先提取所有TXT2的拆分列表,再对每个TXT1列表逐一检查是否存在匹配的TXT2列表。
修正后的主查询代码
let TXT1 = {"RV0003,19915,26966", "RVG002,19923,26966", "NO", "NO", "NO"}, TXT2 = {"NO", "NO", "RV0002,19915,19923,26966", "RV0003,19915,19923,26966", "RVG002,19915,19923,26966"}, TableFromColumns = Table.FromColumns({TXT1, TXT2}, {"TXT1", "TXT2"}), Step_Split_TXT1 = Table.AddColumn(TableFromColumns, "Split_TXT1", each Text.Split([TXT1], ",")), Step_Split_TXT2 = Table.AddColumn(Step_Split_TXT1, "Split_TXT2", each Text.Split([TXT2], ",")), // 提取所有TXT2的拆分列表,缓存避免重复计算 AllSplitTXT2 = List.Buffer(Step_Split_TXT2[Split_TXT2]), // 对每个TXT1列表,遍历所有TXT2列表检查匹配 AddMatchResult = Table.AddColumn(Step_Split_TXT2, "MatchResult", (row) => List.Accumulate(AllSplitTXT2, "NO", (state, txt2List) => if state = "YES" then "YES" else CheckMatch(row[Split_TXT1], txt2List) ) ) in AddMatchResult
修正说明
- 提取所有TXT2列表:用
List.Buffer(Step_Split_TXT2[Split_TXT2])提取所有行的Split_TXT2列表,确保后续遍历的是完整列表而非单个元素。 - 正确传递参数:通过
(row)获取行上下文,直接传入当前行的Split_TXT1列表和每个完整的txt2List,满足CheckMatch的参数类型要求。 - 对齐需求逻辑:
List.Accumulate遍历所有TXT2列表,只要找到一个匹配项就返回"YES",否则返回"NO",实现了“检查TXT1列表是否存在于任意TXT2列表中”的需求。
预期结果
修正后的代码运行后,将生成如下表格:
| TXT1 | TXT2 | Split_TXT1 | Split_TXT2 | MatchResult |
|---|---|---|---|---|
| RV0003,19915,26966 | NO | {"RV0003","19915","26966"} | {"NO"} | YES |
| RVG002,19923,26966 | NO | {"RVG002","19923","26966"} | {"NO"} | YES |
| NO | RV0002,19915,19923,26966 | {"NO"} | {"RV0002","19915","19923","26966"} | YES |
| NO | RV0003,19915,19923,26966 | {"NO"} | {"RV0003","19915","19923","26966"} | YES |
| NO | RVG002,19915,19923,26966 | {"NO"} | {"RVG002","19915","19923","26966"} | YES |
内容的提问来源于stack exchange,提问作者yair_s
相关产品推荐
相关产品推荐

