Excel VBA查找位置连接列表可用路径的递归问题修复求助
修复VBA递归路径查找中的参数传递问题
我一眼就看出你遇到的问题根源——VBA默认的参数传递方式是按引用(ByRef),这就导致递归调用worm时,修改的vlvl和used会直接影响上一层调用的变量状态,死路分支里的节点会被带到后续的正常分支迭代中,生成错误路径。
问题详解
当你的递归走到死路(比如A-B-C-D这条分支),此时used变成了A|B|C|D|,vlvl变成了4。当回溯回C的循环时,因为参数是按引用传递,上层的used和vlvl已经被修改成了死路里的值,后续处理C-Z分支时,就会错误地带上D的节点,生成类似A-B-C-D-Z这种不存在的路径。
修复方案
把worm过程的参数改成按值传递(ByVal),这样每次递归调用都会创建参数的独立副本,下层分支的修改不会影响上层的变量状态。
修改后的完整代码
Sub run_report() Set euh = Sheets("Input") 'B5 and D5 are the two locations to be connected If euh.Range("B5").Value <> "" And euh.Range("D5").Value <> "" Then Call worm(euh.Range("B5").Value, euh.Range("D5").Value, 1, euh.Range("B5").Value & "|") ' "Hops" is where the available paths will be displayed Sheets("Hops").Activate Else MsgBox "Both locations need to be selected!" End If End Sub 'Starting/Current location, End/Goal location, current number of connections used so far, used nodes/locations in this path ' 修改参数为ByVal传递,确保每次递归都是独立的参数副本 Sub worm(ByVal vstart As String, ByVal vend As String, ByVal vlvl As Integer, ByVal used As String) ' "DB" is the connection list database Set sdb = Sheets("DB") Set sh = Sheets("Hops") Dim target As String Dim vline As Integer ' Iterates through all available connections looking for the next step For a = 1 To sdb.Range("A1").End(xlDown).Row If sdb.Range("A" & a).Value = vstart Or sdb.Range("B" & a).Value = vstart Then If sdb.Range("A" & a).Value = vstart Then target = sdb.Range("B" & a).Value Else target = sdb.Range("A" & a).Value End If If target = vend Then 'Add successfull connection Dim finalPath As String finalPath = used & target vline = IIf(sh.Range("A2").Value <> "", sh.Range("A1").End(xlDown).Row + 1, 2) sh.Range("A" & vline).Value = vlvl sh.Range("C" & vline).Value = finalPath 'If the current node/location hasn't been used so far ElseIf InStr(used, target) = 0 Then Dim newUsed As String newUsed = used & target & "|" Call worm(target, vend, (vlvl + 1), newUsed) End If End If Next a End Sub
额外优化说明
我还额外做了两个小优化:
- 拼接路径时使用临时变量(
finalPath、newUsed),让逻辑更清晰,避免直接修改参数(虽然已经是ByVal,但可读性更好) - 明确参数传递方式,让代码维护起来更直观
这样修改后,递归的每个分支都会拥有独立的used路径和vlvl步数,死路分支的修改不会干扰其他正常分支,就能正确生成A-C-Z、A-B-C-Z这类有效路径了。
内容的提问来源于stack exchange,提问作者Lucas Moraes Abarca
相关产品推荐
相关产品推荐

