You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Excel中BOM动态层级结构转换求助:递归函数实现遇阻

解决BOM层级结构转换问题

核心思路

通过递归函数遍历每个父项的所有子项,按层级深度依次填充到目标列中,适配动态变化的层级数量。

VBA实现代码

打开Excel,按Alt+F11打开VBA编辑器,插入新模块,粘贴以下代码:

Option Explicit

' 主函数:启动BOM转换
Sub ConvertBOMToHierarchy()
    Dim sourceSheet As Worksheet
    Dim targetSheet As Worksheet
    Dim lastRow As Long
    Dim parentDict As Object
    Dim i As Long
    
    ' 设置源表和目标表(可根据实际修改)
    Set sourceSheet = ThisWorkbook.Worksheets("Sheet1")
    Set targetSheet = ThisWorkbook.Worksheets("Sheet2")
    Set parentDict = CreateObject("Scripting.Dictionary")
    
    ' 读取所有父-子关系到字典
    lastRow = sourceSheet.Cells(sourceSheet.Rows.Count, "A").End(xlUp).Row
    For i = 2 To lastRow ' 假设第一行是表头
        Dim parentCode As String
        Dim childCode As String
        parentCode = sourceSheet.Cells(i, "A").Value
        childCode = sourceSheet.Cells(i, "B").Value
        
        If Not parentDict.Exists(parentCode) Then
            parentDict(parentCode) = New Collection
        End If
        parentDict(parentCode).Add childCode
    Next i
    
    ' 清空目标表并写入表头
    targetSheet.Cells.Clear
    targetSheet.Cells(1, 1).Value = "层级1"
    targetSheet.Cells(1, 2).Value = "层级2"
    targetSheet.Cells(1, 3).Value = "层级3"
    ' 可按需添加更多表头,代码会自动适配超过的层级
    
    ' 遍历所有顶级父项(即不在子项中的编码)
    Dim topParents As Collection
    Set topParents = GetTopParents(sourceSheet, parentDict)
    Dim topParent As Variant
    Dim targetRow As Long
    targetRow = 2
    
    For Each topParent In topParents
        ' 递归展开顶级父项
        RecurseBOM topParent, 1, targetRow, parentDict, targetSheet
    Next topParent
    
    MsgBox "BOM转换完成!"
End Sub

' 获取所有顶级父项(没有父项的编码)
Function GetTopParents(sourceSheet As Worksheet, parentDict As Object) As Collection
    Dim allChildren As Object
    Dim lastRow As Long
    Dim i As Long
    Dim childCode As String
    Dim parentCode As Variant
    
    Set allChildren = CreateObject("Scripting.Dictionary")
    Set GetTopParents = New Collection
    
    lastRow = sourceSheet.Cells(sourceSheet.Rows.Count, "B").End(xlUp).Row
    ' 收集所有子项编码
    For i = 2 To lastRow
        childCode = sourceSheet.Cells(i, "B").Value
        If Not allChildren.Exists(childCode) Then
            allChildren(childCode) = True
        End If
    Next i
    
    ' 找出不在子项中的父项,即为顶级父项
    For Each parentCode In parentDict.Keys
        If Not allChildren.Exists(parentCode) Then
            GetTopParents.Add parentCode
        End If
    Next parentCode
End Function

' 递归展开BOM层级
Sub RecurseBOM(currentCode As String, currentLevel As Integer, ByRef targetRow As Long, parentDict As Object, targetSheet As Worksheet)
    ' 写入当前层级的编码
    targetSheet.Cells(targetRow, currentLevel).Value = currentCode
    
    ' 如果当前编码有子项,继续递归
    If parentDict.Exists(currentCode) Then
        Dim childCode As Variant
        Dim newRow As Long
        
        For Each childCode In parentDict(currentCode)
            ' 复制当前行的上层编码到新行
            newRow = targetRow + 1
            targetSheet.Rows(targetRow).Copy targetSheet.Rows(newRow)
            ' 写入子项到下一层级
            targetSheet.Cells(newRow, currentLevel + 1).Value = childCode
            ' 递归处理子项
            RecurseBOM childCode, currentLevel + 1, newRow, parentDict, targetSheet
            targetRow = newRow
        Next childCode
    End If
End Sub

使用说明

  1. 将你的BOM数据放在Sheet1的A、B列,第一行设为表头(比如A1="父项编码",B1="子项编码")
  2. 确保Excel启用了“Microsoft Scripting Runtime”(VBA编辑器中,工具→引用→勾选该选项)
  3. 运行ConvertBOMToHierarchy宏,结果会输出到Sheet2中

注意事项

  • 代码会自动识别所有顶级父项并展开,不管层级有多深
  • 如果层级超过预设的表头数量,代码会自动继续往后列填充,无需额外修改表头

内容的提问来源于stack exchange,提问作者Alan Tingey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:42:46