WPS 函数 | 递归!车路线----节点路线全连通查找 !!!

一、帖子开篇

很多朋友做物流站点、路线连通、节点路径查找,都需要根据起点 + 终点,自动找出所有全部连通完整路线。比如我表格里的站点链路:红庙-华隆华隆-合肥合肥-繁华合肥-横溪横溪-繁华红庙-昆山昆山-芜湖芜湖-繁华给定一组起点-终点,自动遍历所有连通路径,把整条串联路线完整提取出来。

今天直接把我这套纯 WPS 原生函数、无 VBA、纯 LET + 多层 LAMBDA 递归、正则动态匹配的完整公式,从函数定义、每一层 Lambda 含义、递归循环逻辑、正则拼接坑、整条公式运行全流程,从头到尾掰开揉碎讲清楚,附带每一行代码注释、底层原理、新手易错点。

你的完整原始公式(先放全文):

excel

=LET(

下一站,

LAMBDA(a, FILTER(LEFT(a, LEN(a) - 2) & B:B, RIGHT(a, 2) = LEFT(B:B, 2), a)),

下站循环,

LAMBDA(a, IF(ROWS(a) = 1, 下一站(a), VSTACK(下一站(TAKE(a, 1)), 下站循环(DROP(a, 1))))),

终点循环,

LAMBDA(a, IF(AND(IFNA(下站循环(a) = a, )), a, 终点循环(下站循环(a)))),

判断提取,

LAMBDA(a,

TOCOL(UNIQUE(REGEXEXTRACT(终点循环(MID(a, 1, 2)), ".*"&MID(a, 4, 2)&""), 3))),

判断提取(E10))


二、业务场景 & 表格数据源

先统一所有背景,所有人都能看懂:

  1. 数据源区域B列,全部是单向路段,格式统一 起点-终点

例:红庙-华隆合肥-繁华芜湖-繁华

  1. 查询格式:你 E 列的查询单元格,统一格式 起点-终点

例:红庙-繁华合肥-繁华

  1. 公式需求

输入任意一组起点-终点自动递归遍历所有连通路段,输出全部完整串联路线

比如查询红庙-繁华,自动输出全部 3 条连通路径:

plaintext

红庙-华隆-合肥-繁华

红庙-华隆-合肥-横溪-繁华

红庙-昆山-芜湖-繁华

  1. 技术栈全部原生函数:LET容器 + 4 层自定义LAMBDA函数 + 多层递归 + FILTER数组遍历 + VSTACK数组堆叠 + MID文本截取 + REGEXEXTRACT正则动态匹配 + UNIQUE去重 + TOCOL一维数组展开


三、逐行逐函数完整拆解

LET函数的本质:提前定义好所有自定义函数 / 变量,后面统一调用,公式整洁、只计算一次、不重复运算。里面依次定义了 4 个自定义函数:下一站下站循环终点循环判断提取,层层嵌套、层层递归,我逐个讲透。

1. 第一层自定义函数:下一站

excel

下一站,

LAMBDA(a, FILTER(LEFT(a, LEN(a) - 2) & B:B, RIGHT(a, 2) = LEFT(B:B, 2), a)),

函数含义(核心基础函数,整条公式的地基)

自定义函数名:下一站(a)传入一个路段文本a,自动查找这个路段的终点,在 B 列所有路段里,能衔接上的「下一段完整路段」

逐代码字符拆解

  1. LAMBDA(a, ...)

定义匿名函数,形参a:就是你传入的当前路段(比如红庙-华隆

  1. RIGHT(a, 2)

截取传入路段a最后 2 个字符,也就是当前路段的【终点】

例:传入红庙-华隆RIGHT(a,2) → 结果华隆

  1. LEFT(B:B, 2)

批量提取整个 B 列所有路段,每一条的前 2 个字符,也就是每一条路段自身的【起点】

  1. 匹配条件 RIGHT(a, 2) = LEFT(B:B, 2)

筛选逻辑:上一条路的终点 = 下一条路的起点,也就是能首尾衔接的路段

  1. LEFT(a, LEN(a) - 2) & B:B

路段拼接核心!

  • LEFT(a, LEN(a)-2):把传入的原路段a去掉末尾的终点,保留完整前缀路径

  • & B:B:把前缀路径,和后面匹配到的衔接路段,全部拼接起来,形成更长的串联路径

例:传入红庙-华隆,匹配到华隆-合肥,拼接后直接生成 红庙-华隆-合肥

  1. FILTER(拼接结果, 衔接条件, a)

  • 满足衔接条件,就返回拼接好的更长路径

  • 兜底参数a:如果找不到下一站、无路可走了,就原路返回自身,防止公式报错、数组断裂

  1. 总结作用

只做一件事:给定一条路径,自动找所有能接上的下一段路,并且直接拼接成长路径,是所有递归循环的基础单元。


2. 第二层自定义函数:下站循环

excel

下站循环,

LAMBDA(a, IF(ROWS(a) = 1, 下一站(a), VSTACK(下一站(TAKE(a, 1)), 下站循环(DROP(a, 1))))),

函数含义

自定义函数名:下站循环(a)数组批量循环版的「下一站」解决问题:上一层下一站只能处理单条路径,这个函数可以处理一整个路径数组,数组里每一条路径,全部独立去跑下一站查找,互不干扰,递归遍历。

逐代码字符拆解

  1. LAMBDA(a, ...)

形参a:传入的路径数组(多条路径组成的一维数组)

  1. IF(ROWS(a) = 1, 下一站(a), ...)

IF 分支判断,递归终止判断条件:

  • 当数组a只有1 行(单条路径):直接调用第一层下一站(a),找它的下一站拼接

  • 当数组有多行多条路径:走后面的数组拆分递归逻辑

  1. TAKE(a, 1)

提取数组a第 1 行(第一条路径),单独拿出来

  1. 下一站(TAKE(a, 1))

单独给第一条路径,跑一遍「找下一站 + 拼接」

  1. DROP(a, 1)

把数组a去掉第一行,拿到剩下所有的其余路径

  1. 下站循环(DROP(a, 1))

自身递归调用! 把剩下的路径数组,再次扔进下站循环函数里,循环处理

  1. VSTACK(...)

把「第一条路径的结果」+「剩余数组递归完的全部结果」,上下堆叠合并成一个完整新数组

  1. 递归逻辑全程白话

拿到一堆路径数组先处理第一条,剩下的一整堆,再丢回自己这个函数重新跑直到数组里只剩单条路径,触发终止条件,调用基础下一站全部跑完,全部结果堆成新数组返回

3. 第三层自定义函数:终点循环

excel

终点循环,

LAMBDA(a, IF(AND(IFNA(下站循环(a) = a, )), a, 终点循环(下站循环(a)))),

函数含义

自定义函数名:终点循环(a)整条公式的灵魂!深度递归遍历全链路传入一个初始起点路径,无限循环找下一站、拼接路径,直到走到死胡同、再也没有能衔接的路段为止,自动走完从起点出发的所有全部连通完整路线。

逐代码字符拆解

  1. LAMBDA(a, ...)

形参a:传入的初始起点(你后面 MID 截取出来的起点文本)

  1. 核心递归终止条件 IF(AND(IFNA(下站循环(a) = a, )), a, ...)

我拆开这个嵌套条件,新手最容易懵的地方:

  • 下站循环(a):把当前路径,跑一遍全数组找下一站,得到新一轮延伸后的路径

  • 下站循环(a) = a:判断延伸后的路径,和原来的路径是不是完全一模一样

含义:找不到任何新的衔接路段了,无路可走、已经走到链路终点了

  • IFNA(...,):屏蔽无匹配报错,找不到结果时返回逻辑值,防止数组报错中断

  • AND(...):全数组判断,所有路径全部无路可走,整体判定终止

  • 条件成立(无路可走):a 直接返回当前已经走完的完整路径

  1. 递归分支 终点循环(下站循环(a))

自身无限递归

只要还能找到下一站、路径还能延伸,就:

当前路径 → 跑下站循环延伸变长 → 把新路径,再次丢回终点循环自身函数,继续找下一站、继续拼接

  1. 全程递归白话逻辑(重中之重)

plaintext

传入初始起点

第一步:找所有能衔接的下一站,拼接成长路径

判断:还能不能继续往后走?

能走 → 把新路径重新扔进自己函数,继续延伸

不能走(无路可走)→ 停止递归,返回最终完整全链路路径

完美实现从起点开始,深度遍历所有连通支路,走完所有路线


4. 第四层自定义函数:判断提取

excel

判断提取,

LAMBDA( a,

TOCOL(UNIQUE(REGEXEXTRACT(终点循环(MID(a, 1, 2)), ".*"&MID(a, 4, 2)&""), 3))),

函数含义

自定义函数名:判断提取(a)对外最终调用入口,承接前面所有递归,完成「查询文本拆分→起点递归全遍历→终点正则筛选→去重→数组展开」全部收尾工作,你最后表格里只需要调用这个函数即可。

逐代码字符拆解(顺带把你之前问的所有正则坑全部讲透)

  1. LAMBDA(a, ...)

形参a:就是你表格里 E 列的完整查询单元格,格式固定 起点-终点

例:a = 红庙-繁华

  1. MID(a, 1, 2)

截取查询文本a的前 2 个字符 → 查询起点

例:红庙-繁华 → 截取结果 红庙

  1. 终点循环(MID(a, 1, 2))

把上面截取的起点,扔进我们第三层写好的终极递归函数

自动从起点开始,深度遍历所有连通路线,拼接出所有从该起点出发、能走到的全部完整长路径

  1. MID(a, 4, 2)

截取查询文本a第 4 位开始的 2 个字符 → 查询终点

例:红庙-繁华 → 截取结果 繁华

  1. 重点!正则拼接写法(你之前反复问的「正则里面嵌套函数」终极正确写法)

excel

".*"&MID(a, 4, 2)&""

这里把你之前所有踩过的坑一次性讲明白:

  • 错误写法(你之前写的):".*&MID(a,4,2)&.*"

双引号把所有内容全包死,&MID函数全部被当成纯文本字符,函数完全不计算

  • 正确拼接铁则:固定正则字符写在引号内,函数 / 单元格全部切出引号,用 & 连接符拼接

前缀固定 .* → 写在引号里 "."*

中间动态终点 → 放外面 MID(a,4,2)

后缀固定内容 → 写在引号里 ""

最终拼接:".*"&MID(a,4,2)&""

  • 正则含义:.* 贪婪匹配前面所有内容,只要路径末尾包含我们查询的终点,就全部匹配提取

  1. REGEXEXTRACT(递归全量路径数组, 上面拼接好的动态正则)

从递归跑出来的所有起点全链路里,精准筛选出末尾刚好是你查询终点的所有有效路线,过滤掉所有走到其他终点的无效路径

  1. UNIQUE(..., 3)

数组去重,参数3整行完全重复才剔除,保留所有不重复的独立连通路线

  1. TOCOL(...)

把最终筛选完的所有路线,全部展开成整齐单列,从上到下竖排显示,完美适配你 E 列单元格输出格式

  1. 末尾最终调用

excel

判断提取(E10)

整个 LET 公式的出口:直接传入你 E10 单元格的起点-终点查询值,全部流程跑完,输出全部完整连通路线。


四、整条公式完整递归全流程串讲

用你表格里 E10 单元格查询 红庙-繁华 完整走一遍,一眼看懂全链路:

  1. 调用 判断提取(E10)

  1. 拆分查询文本:MID(E10,1,2) 拿到起点红庙MID(E10,4,2) 拿到终点繁华

  1. 起点红庙传入 终点循环 终极递归函数

  • 第 1 轮:红庙 → 找下一站,得到 红庙-华隆红庙-昆山

  • 第 2 轮:各自继续延伸 → 红庙-华隆-合肥红庙-昆山-芜湖

  • 第 3 轮:继续延伸 → 红庙-华隆-合肥-繁华红庙-华隆-合肥-横溪

  • 第 4 轮:继续延伸 → 红庙-华隆-合肥-横溪-繁华红庙-昆山-芜湖-繁华

  • 全部路径走到终点、无路可走,递归停止,返回全部 4 条完整路径

  1. 动态正则筛选:.*繁华,从全部路径里,只保留末尾是繁华的全部路线

  1. 去重 + TOCOL 展开单列,最终输出:

plaintext

红庙-华隆-合肥-繁华

红庙-华隆-合肥-横溪-繁华

红庙-昆山-芜湖-繁华

和你表格 E 列预期结果完全一模一样!


五、新手必看易错点 & 公式亮点总结

  1. 正则贪婪.* 用法、非贪婪区分

  1. 正则内嵌套函数 / MID 截取:引号拼接铁则,函数绝对不能塞进双引号内部

  1. [一-龟]中文区间、连续字符匹配基础

  1. LET 多 Lambda 自定义函数分层管理

  1. LAMBDA 自身递归调用、递归终止条件写法

  1. TAKE/DROP 数组拆分、VSTACK 数组堆叠批量处理

  1. UNIQUE+TOCOL 数组收尾规整

  1. 递归函数一定要写终止条件!你公式里终点循环IF(下站循环(a)=a)就是终止阀,没有会无限递归公式报错

  1. 正则拼接函数,绝对不要把函数写在双引号内部,所有函数、单元格全部拉到引号外用&拼接

  1. 数组递归一定要用 VSTACK 做堆叠,不然多条路径会覆盖丢失

浙江省
浏览 133
1
11
分享
11 +1
3
1 +1
全部评论 3
 
༺娃娃鱼༻
太强啦,不懂先点赞👍
· 山东省
回复
 
南京的天
你好,可以上传示例工作簿截图吗?感觉比存文字描述要更好一点
· 山西省
回复
 
user_64801
直接用ai函数吧
· 云南省
回复