VBA获取树形结构中指定节点的所有终端子节点问题求助
VBA获取树形结构中指定节点的所有终端子节点问题求助
嗨,看了你的问题,你是想从Parent-Child结构的表格里,找到指定节点的所有终端子节点(也就是没有自己子节点的叶子节点)对吧?你提到递归方法已经接近了,但会带出中间节点甚至原节点,确实只需要加个判断就能搞定。
先再明确下你的数据示例,方便大家理解:
| Parent | Child |
|---|---|
| A | A1 |
| A | A2 |
| A1 | A1.1 |
| A1 | A1.2 |
| A1 | A1.3 |
| A2 | A2.1 |
| A1.2 | A1.2.1 |
| A1.2 | A1.2.2 |
比如输入节点A1,需要得到的是{A1.1, A1.2.1, A1.2.2, A1.3},这些都是没有子节点的叶子节点。
你的递归思路是对的,问题出在没有判断当前节点是不是终端节点(也就是这个节点有没有出现在Parent列里)。我们可以做两个关键优化:
- 递归过程中,只收集那些不在Parent列中的节点(也就是没有子节点的终端节点)
- 自动跳过初始的指定节点本身,避免它被加入结果
下面是修正后的VBA代码,你可以直接用:
Function GetTerminalChildren(targetNode As String, ws As Worksheet) As Collection Dim result As New Collection Dim parentRng As Range, cell As Range ' 遍历Parent列,找到所有当前节点的直接子节点 Set parentRng = ws.Range("A2:A" & ws.Cells(ws.Rows.Count, "A").End(xlUp).Row) For Each cell In parentRng If cell.Value = targetNode Then Dim childNode As String childNode = ws.Cells(cell.Row, "B").Value ' 判断这个子节点是不是终端节点:检查它有没有出现在Parent列里 If IsError(Application.Match(childNode, parentRng, 0)) Then ' 是终端节点,加入结果 result.Add childNode Else ' 不是终端节点,递归找它的终端子节点 Dim subChildren As Collection Set subChildren = GetTerminalChildren(childNode, ws) Dim subChild As Variant For Each subChild In subChildren result.Add subChild Next subChild End If End If Next cell Set GetTerminalChildren = result End Function ' 测试用的子过程 Sub TestGetTerminalChildren() Dim ws As Worksheet Set ws = ThisWorkbook.Worksheets("Sheet1") ' 改成你的工作表名 Dim targetNode As String targetNode = "A1" ' 改成你要查询的节点 Dim terminalChildren As Collection Set terminalChildren = GetTerminalChildren(targetNode, ws) ' 输出结果到立即窗口 Debug.Print "终端子节点列表:" Dim child As Variant For Each child In terminalChildren Debug.Print child Next child End Sub
代码说明:
GetTerminalChildren函数接收目标节点和工作表对象,返回一个存储终端子节点的Collection- 核心判断:用
Application.Match检查子节点是否存在于Parent列,如果找不到(返回错误),说明是终端节点,直接加入结果;如果存在,就递归查找这个子节点的终端子节点,把结果合并进来 - 因为我们只处理目标节点的子节点,所以天然不会把目标节点本身加入结果
你可以把工作表名改成你实际的表名,然后运行TestGetTerminalChildren测试,就能得到干净的终端子节点列表啦。
备注:内容来源于stack exchange,提问作者ziggy41
相关产品推荐
相关产品推荐

