Files
AutoBOM/reference_docs/clsBOMManager使用说明.md
Misaka_Company fd414f7673 docs: reorganize documentation structure and add analysis guidelines
- Move existing documentation files to reference_docs/ directory
- Add documentation guidelines section to CLAUDE.md
- Add clsBOMManager LoadData flow analysis with Mermaid diagrams

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-29 09:30:29 +08:00

15 KiB
Raw Blame History

clsBOMManager 类使用说明

概述

clsBOMManager 是 AutoBOM 系统的核心控制器类,负责管理整个 BOM物料清单数据结构。它从 Excel 工作表加载数据,构建层级化的类别树,并提供物料查询和领料逻辑处理功能。


类初始化

Dim bomMgr As New clsBOMManager

创建实例时,会自动初始化以下内部数据结构:

  • dictCategories - 类别字典(类别名称 → clsCategory 对象)
  • dictAllMaterials - 物料字典(物料代号 → clsMaterialItem 对象)
  • rootCategories - 根类别集合(顶层类别)

公开方法

1. LoadData 方法

功能:从 Excel 工作表加载 BOM 数据并构建数据结构

语法

Public Sub LoadData(wsConfig As Worksheet, wsPlatform As Worksheet)

参数

参数 类型 说明
wsConfig Worksheet 领料配置工作表,定义类别层级和需要领料的物料
wsPlatform Worksheet 平台配置清单工作表,包含完整的物料信息

数据要求

领料配置 工作表格式:

  • 第 1 行:标题行
  • 第 2 行起:数据行
    • A 列:物料代号
    • C 列:类别名称
    • D 列:上层类别名称

平台配置清单 工作表格式:

  • 第 1-3 行:标题行
  • 第 4 行起:数据行
    • C 列:物料代号
    • D 列:物料名称
    • E 列:物料数量
    • F 列:选择条件

处理逻辑

  1. 从"平台配置清单"加载所有物料的基础信息到 dictAllMaterials
  2. 从"领料配置"加载类别信息,筛选需要领料的物料
  3. 建立类别的父子关系,构建层级树

重要说明

  • 只有出现在"领料配置"中的物料才会被添加到类别中
  • 未在"领料配置"中的物料表示不需要领料,但仍存在于物料字典中

使用示例

Dim bomMgr As New clsBOMManager
Dim wsConfig As Worksheet
Dim wsPlatform As Worksheet

Set wsConfig = ThisWorkbook.Worksheets("领料配置")
Set wsPlatform = ThisWorkbook.Worksheets("平台配置清单")

bomMgr.LoadData wsConfig, wsPlatform

2. GetRootCategories 方法

功能:获取所有顶层类别的集合

语法

Public Function GetRootCategories() As Collection

返回值

  • Collection 对象,包含所有无父类别的 clsCategory 对象

用途

  • 遍历整个 BOM 结构时的入口点
  • 生成领料清单时遍历所有根类别

使用示例

Dim rootCats As Collection
Dim cat As clsCategory
Dim i As Long

Set rootCats = bomMgr.GetRootCategories()

For i = 1 To rootCats.Count
    Set cat = rootCats(i)
    Debug.Print "根类别: " & cat.categoryName
    Debug.Print "  物料数: " & cat.Materials.Count
    Debug.Print "  子类别数: " & cat.SubCategories.Count
Next i

3. GetCategory 方法

功能:根据类别名称获取类别对象

语法

Public Function GetCategory(categoryName As String) As clsCategory

参数

参数 类型 说明
categoryName String 要查询的类别名称

返回值

  • 找到时:返回 clsCategory 对象
  • 未找到时:返回 Nothing

用途:快速查找特定类别及其下的物料

使用示例

Dim cat As clsCategory
Set cat = bomMgr.GetCategory("部件")

If Not cat Is Nothing Then
    Debug.Print "类别: " & cat.categoryName
    Debug.Print "父类别: " & cat.ParentCategoryName
    Debug.Print "物料数: " & cat.Materials.Count
    Debug.Print "是否叶子类别: " & cat.IsLeafCategory
End If

4. GetMaterialsForPicking 方法

功能:获取某类别下需要领料的物料清单(支持层级逻辑)

语法

Public Function GetMaterialsForPicking(categoryName As String, _
                                      Optional useParent As Boolean = True) As Collection

参数

参数 类型 默认值 说明
categoryName String - 类别名称
useParent Boolean True 领料方式True=父类别物料False=子类别物料

返回值

  • Collection 对象,包含 clsMaterialItem 对象

业务逻辑说明

父类别模式 (useParent=True)

  • 这是默认的领料方式
  • 直接返回当前类别下的所有物料
  • 即使该类别有子类别,也仍然返回父类别物料
  • 用于领取组装好的部件

示例

' 获取"部件"类别的父类别物料
Set materials = bomMgr.GetMaterialsForPicking("部件", True)
' 返回:低压接头部件、高压接头部件等组装好的部件

子类别模式 (useParent=False)

  • 这是库存不足时的替代方案
  • 如果当前类别有子类别,递归获取所有子类别的物料
  • 如果当前类别是叶子类别(无子类别),返回本类别物料
  • 用于父类别库存不足,需要领取零件自行组装的情况

示例

' 获取"部件"类别的子类别展开物料
Set materials = bomMgr.GetMaterialsForPicking("部件", False)
' 返回:径向低压接头、弹簧管、螺旋管等零件

层级结构示例

部件 (父类别)
├── 低压接头部件 (物料)
├── 高压接头部件 (物料)
└── 接头 (子类别)
    ├── 径向低压接头 (物料)
    ├── 轴向高压接头 (物料)
    └── 弹性元件 (孙类别)
        └── 弹簧管 (物料)

使用示例

Dim materials As Collection
Dim mat As clsMaterialItem
Dim i As Long

' 默认使用父类别物料
Set materials = bomMgr.GetMaterialsForPicking("部件", True)
Debug.Print "父类别物料数: " & materials.Count

For i = 1 To materials.Count
    Set mat = materials(i)
    Debug.Print mat.code & " - " & mat.Name & _
               " | 数量:" & mat.Quantity & _
               " | 条件:" & mat.Condition
Next i

' 库存不足时,使用子类别物料
Set materials = bomMgr.GetMaterialsForPicking("部件", False)
Debug.Print "子类别展开物料数: " & materials.Count

5. PrintCategoryTree 方法

功能:将类别树结构打印到工作表(用于调试和查看)

语法

Public Sub PrintCategoryTree(ws As Worksheet)

参数

参数 类型 说明
ws Worksheet 输出的目标工作表对象

输出格式

  • 第 1 列:类别名称(带缩进显示层级)
  • 第 2 列:物料数量信息
  • 第 3 列:选择条件

缩进规则:每层级 2 个空格

输出示例

表壳 (物料数:1)
  - 01091004312 表壳(本色)  数量:1  条件:
部件 (物料数:20)
  - 01011019001 低压接头部件  数量:1  条件:lcfw=M02...
  接头 (物料数:18)
    - 01081013833 径向低压接头  数量:1  条件:gclj=Z12...

使用示例

Dim wsOutput As Worksheet

' 创建新工作表
On Error Resume Next
Application.DisplayAlerts = False
ThisWorkbook.Worksheets("BOM结构").Delete
Application.DisplayAlerts = True
On Error GoTo 0

Set wsOutput = ThisWorkbook.Worksheets.Add
wsOutput.Name = "BOM结构"

' 打印类别树
bomMgr.PrintCategoryTree wsOutput

典型使用场景

场景 1生成领料清单

Sub GeneratePickingList()
    Dim bomMgr As New clsBOMManager
    Dim wsConfig As Worksheet, wsPlatform As Worksheet
    Dim wsPickList As Worksheet
    Dim rootCats As Collection
    Dim cat As clsCategory
    Dim materials As Collection
    Dim mat As clsMaterialItem
    Dim row As Long
    Dim i As Long, j As Long

    ' 1. 加载数据
    Set wsConfig = ThisWorkbook.Worksheets("领料配置")
    Set wsPlatform = ThisWorkbook.Worksheets("平台配置清单")
    bomMgr.LoadData wsConfig, wsPlatform

    ' 2. 创建输出工作表
    Application.DisplayAlerts = False
    On Error Resume Next
    ThisWorkbook.Worksheets("领料清单").Delete
    On Error GoTo 0
    Application.DisplayAlerts = True

    Set wsPickList = ThisWorkbook.Worksheets.Add
    wsPickList.Name = "领料清单"

    ' 3. 写入表头
    row = 1
    wsPickList.Cells(row, 1).Value = "代号"
    wsPickList.Cells(row, 2).Value = "名称"
    wsPickList.Cells(row, 3).Value = "类别"
    wsPickList.Cells(row, 4).Value = "数量"
    wsPickList.Cells(row, 5).Value = "选择条件"
    wsPickList.Cells(row, 6).Value = "领料方式"
    row = row + 1

    ' 4. 遍历所有根类别并生成清单
    Set rootCats = bomMgr.GetRootCategories

    For i = 1 To rootCats.Count
        Set cat = rootCats(i)
        ' 默认使用父类别物料
        Set materials = bomMgr.GetMaterialsForPicking(cat.categoryName, True)

        For j = 1 To materials.Count
            Set mat = materials(j)
            wsPickList.Cells(row, 1).Value = mat.code
            wsPickList.Cells(row, 2).Value = mat.Name
            wsPickList.Cells(row, 3).Value = mat.Category
            wsPickList.Cells(row, 4).Value = mat.Quantity
            wsPickList.Cells(row, 5).Value = mat.Condition
            wsPickList.Cells(row, 6).Value = "父类别"
            row = row + 1
        Next j
    Next i

    ' 5. 格式化表格
    wsPickList.Range("A1:F1").Font.Bold = True
    wsPickList.Columns("A:F").AutoFit

    MsgBox "领料清单生成完成!", vbInformation
End Sub

场景 2查询特定类别信息

Sub QueryCategoryInfo()
    Dim bomMgr As New clsBOMManager
    Dim wsConfig As Worksheet, wsPlatform As Worksheet
    Dim cat As clsCategory
    Dim mat As clsMaterialItem
    Dim subCat As clsCategory
    Dim i As Long

    ' 加载数据
    Set wsConfig = ThisWorkbook.Worksheets("领料配置")
    Set wsPlatform = ThisWorkbook.Worksheets("平台配置清单")
    bomMgr.LoadData wsConfig, wsPlatform

    ' 查询特定类别
    Set cat = bomMgr.GetCategory("部件")

    If Not cat Is Nothing Then
        Debug.Print "========== 类别信息 =========="
        Debug.Print "类别名称: " & cat.categoryName
        Debug.Print "父类别: " & cat.ParentCategoryName
        Debug.Print "物料数量: " & cat.Materials.Count
        Debug.Print "子类别数量: " & cat.SubCategories.Count
        Debug.Print "是否叶子类别: " & cat.IsLeafCategory
        Debug.Print ""

        ' 列出所有物料
        Debug.Print "---------- 物料列表 ----------"
        For i = 1 To cat.Materials.Count
            Set mat = cat.Materials(i)
            Debug.Print "  " & mat.code & ": " & mat.Name & _
                       " (数量:" & mat.Quantity & _
                       ", 条件:" & mat.Condition & ")"
        Next i
        Debug.Print ""

        ' 列出所有子类别
        Debug.Print "---------- 子类别列表 ----------"
        For i = 1 To cat.SubCategories.Count
            Set subCat = cat.SubCategories(i)
            Debug.Print "  " & subCat.categoryName & _
                       " (物料数:" & subCat.Materials.Count & ")"
        Next i
    Else
        Debug.Print "类别不存在"
    End If
End Sub

场景 3根据库存情况选择领料方式

Sub SmartPicking()
    Dim bomMgr As New clsBOMManager
    Dim materials As Collection
    Dim mat As clsMaterialItem
    Dim categoryName As String
    Dim i As Long

    ' 加载数据
    bomMgr.LoadData _
        ThisWorkbook.Worksheets("领料配置"), _
        ThisWorkbook.Worksheets("平台配置清单")

    categoryName = "部件"

    ' 尝试获取父类别物料
    Set materials = bomMgr.GetMaterialsForPicking(categoryName, True)

    ' 检查库存是否充足(这里需要连接实际的库存系统)
    Dim isStockSufficient As Boolean
    isStockSufficient = CheckStock(materials) ' 假设的库存检查函数

    If isStockSufficient Then
        Debug.Print "使用父类别领料方式"
    Else
        Debug.Print "父类别库存不足,改用子类别领料方式"
        Set materials = bomMgr.GetMaterialsForPicking(categoryName, False)
    End If

    ' 输出物料清单
    For i = 1 To materials.Count
        Set mat = materials(i)
        Debug.Print mat.code & " " & mat.Name
    Next i
End Sub

辅助类说明

clsCategory 类

表示物料类别及其层级关系。

公共属性

属性 类型 说明
categoryName String 类别名称
ParentCategoryName String 父类别名称
Materials Collection 该类别下的物料集合
SubCategories Collection 子类别集合
IsLeafCategory Boolean 是否为叶子类别(无子类别)

公共方法

  • AddMaterial(mat As clsMaterialItem) - 添加物料
  • AddSubCategory(cat As clsCategory) - 添加子类别
  • GetMaterial(code As String) As clsMaterialItem - 获取指定代号的物料
  • HasSubCategories() As Boolean - 检查是否有子类别

clsMaterialItem 类

表示单个物料项。

公共属性

属性 类型 说明
code String 物料代号
Name String 物料名称
Quantity Double 物料数量
Condition String 选择条件
Category String 所属类别
ParentCategory String 上层类别

注意事项

  1. 数据加载顺序:必须先调用 LoadData() 方法,才能使用其他查询方法

  2. 工作表名称:确保工作表名称与代码中的名称一致:

    • "领料配置"
    • "平台配置清单"
  3. 空值处理:使用 GetCategory() 方法时,务必检查返回值是否为 Nothing

  4. 领料方式选择

    • 正常情况使用 useParent=True(领取组装好的部件)
    • 仅在库存不足时使用 useParent=False(领取零件自行组装)
  5. 数据一致性:修改 Excel 数据后,需要重新调用 LoadData() 重新加载数据

  6. 内存管理使用完毕后VBA 会自动清理对象,无需手动释放


常见问题

Q1: 如何判断某个类别是否存在?

Dim cat As clsCategory
Set cat = bomMgr.GetCategory("类别名")

If Not cat Is Nothing Then
    ' 类别存在
Else
    ' 类别不存在
End If

Q2: 如何获取所有类别的名称?

Sub ListAllCategories()
    ' 需要递归遍历所有类别
    ' 可以使用 PrintCategoryTree 方法输出到工作表查看
End Sub

Q3: 父类别和子类别物料有什么区别?

  • 父类别物料:组装好的成品部件,如"低压接头部件"
  • 子类别物料:组成部件的零件,如"径向低压接头"、"弹簧管"等

Q4: 如何处理物料选择条件?

Dim mat As clsMaterialItem
' ...
If mat.Condition <> "" Then
    ' 根据条件选择合适的物料
    ' 条件格式如lcfw=M02;gclj=Z12
    ' 需要根据产品配置解析这些条件
End If

版本信息

  • 类名称clsBOMManager
  • 版本1.0
  • 最后更新2025
  • 依赖类clsCategory, clsMaterialItem