递归子程序确定BOM物料层级计数错误,求技术指导
BOM递归层级计数问题修复方案
核心问题分析
你的VBA代码层级计数错误的关键原因:
- 用ByRef传递层级变量
l,递归调用时会直接修改原变量值,回溯时无法自动恢复层级,导致后续子节点的层级被错误累加。 - 递归调用的起始行、物料定位逻辑存在偏移错误,
Cells(a, 2).Offset(2, 0)和a + 2的设置可能不符合你的BOM结构排版,容易跳过或错误定位子物料。
修复后的完整代码
Public eof As Long Sub RecursiveSearch() Dim i As Long Dim ws As Worksheet Dim art_to_search As String Dim str_art As Integer Set ws = ThisWorkbook.Worksheets("Sheet1") ' 替换为你的实际工作表名 eof = ws.Cells.Find("*", ws.[A1], , , xlByRows, xlPrevious).Row ' 计算数据最后一行 ' 遍历所有行,定位顶层物料(长度为15的编码) For i = 1 To eof art_to_search = ws.Cells(i, 2).Value str_art = Len(art_to_search) If str_art = 15 Then Debug.Print i & " " & art_to_search ' 传递初始层级1,用ByVal避免全局修改层级变量 Call ArticleExists(art_to_search, i + 1, eof, 1, ws) End If Next i End Sub Sub ArticleExists(ByVal article As String, ByVal startRow As Long, ByVal lastRow As Long, ByVal currentLevel As Integer, ByVal ws As Worksheet) Dim a As Long Dim nextLevel As Integer nextLevel = currentLevel + 1 ' 遍历起始行到最后一行,查找匹配的父物料 For a = startRow To lastRow If Trim(article) = Trim(ws.Range("A" & a).Value) Then ' 写入当前节点的层级 ws.Range("D" & a) = nextLevel ' 获取当前节点的子物料编码(根据你的BOM结构调整列,这里用B列) Dim childArticle As String childArticle = ws.Cells(a, 2).Value ' 递归查找子物料的下层节点,起始行设为当前行+1(根据结构调整) Call ArticleExists(childArticle, a + 1, lastRow, nextLevel, ws) ' 注意:如果一个父物料对应多个子物料,不要加Exit Sub,否则只会处理第一个匹配项 End If Next a End Sub
关键修改说明
- 层级传递改为ByVal:每次递归调用时传递当前层级的副本,回溯时不会影响上层的层级计数,确保每个节点的层级基于父节点正确计算。
- 添加工作表对象参数:避免依赖ActiveSheet,防止切换工作表时出错,代码更健壮。
- 移除Exit Sub:如果BOM中一个父物料对应多个子物料,保留
Exit Sub会只处理第一个匹配项,移除后能遍历所有子节点。 - 修正物料定位逻辑:原代码的偏移设置不符合常规BOM结构,改为直接取当前行B列作为子物料编码,起始行设为当前行+1,你可根据实际BOM的排版(比如缩进、行间距)进一步调整。
测试建议
在写入层级到D列时,可添加Debug输出辅助排查:
Debug.Print "行" & a & " 物料:" & ws.Range("A" & a).Value & " 层级:" & nextLevel
内容的提问来源于stack exchange,提问作者wiwi_99
相关产品推荐
相关产品推荐

