From fd414f767308edecdbd1f425016671339c725e81 Mon Sep 17 00:00:00 2001 From: Misaka_Company Date: Thu, 29 Jan 2026 09:30:29 +0800 Subject: [PATCH] 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 --- CLAUDE.md | 12 + ...Example1_GeneratePickingListByModel_时序图.md | 0 .../clsBOMManager_LoadData流程分析.md | 439 ++++++++++++++++++ .../clsBOMManager使用说明.md | 0 {VBA => reference_docs}/combined_output.md | 0 .../型号解析与物料匹配系统 - 使用说明.md | 0 .../布莱迪公司压力表产品选型大表.md | 0 .../新增条件提取计划.md | 0 8 files changed, 451 insertions(+) rename Example1_GeneratePickingListByModel_时序图.md => reference_docs/Example1_GeneratePickingListByModel_时序图.md (100%) create mode 100644 reference_docs/clsBOMManager_LoadData流程分析.md rename {VBA => reference_docs}/clsBOMManager使用说明.md (100%) rename {VBA => reference_docs}/combined_output.md (100%) rename 型号解析与物料匹配系统 - 使用说明.md => reference_docs/型号解析与物料匹配系统 - 使用说明.md (100%) rename 布莱迪公司压力表产品选型大表.md => reference_docs/布莱迪公司压力表产品选型大表.md (100%) rename 新增条件提取计划.md => reference_docs/新增条件提取计划.md (100%) diff --git a/CLAUDE.md b/CLAUDE.md index fcf665f..c9f2a6b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -130,6 +130,18 @@ Run tests from the VBA editor or Excel macros: - `布莱迪公司压力表产品选型大表.md` - Complete product model numbering system (716 lines, Chinese) - `VBA/clsBOMManager使用说明.md` - API documentation and usage examples for clsBOMManager (546 lines, Chinese) +### Documentation Guidelines + +**Analysis Documents** +- When analyzing VBA code, modules, or methods (e.g., creating flow diagrams, architecture explanations), save all generated analysis documents to the `reference_docs/` directory +- Use descriptive filenames that clearly indicate the content (e.g., `clsBOMManager_LoadData流程分析.md`) +- Prefer using Mermaid diagrams for visualizing: + - Flowcharts (method execution flow) + - Sequence diagrams (interactions between objects) + - Class diagrams (relationships between classes) + - State diagrams (state transitions) +- Keep analysis documents in Chinese when the original code comments are in Chinese + ## Module Registry `VBA/vba_metadata.json` maps VBA module names to their file locations in the repository. Update this file when: diff --git a/Example1_GeneratePickingListByModel_时序图.md b/reference_docs/Example1_GeneratePickingListByModel_时序图.md similarity index 100% rename from Example1_GeneratePickingListByModel_时序图.md rename to reference_docs/Example1_GeneratePickingListByModel_时序图.md diff --git a/reference_docs/clsBOMManager_LoadData流程分析.md b/reference_docs/clsBOMManager_LoadData流程分析.md new file mode 100644 index 0000000..837de1f --- /dev/null +++ b/reference_docs/clsBOMManager_LoadData流程分析.md @@ -0,0 +1,439 @@ +# clsBOMManager.LoadData 方法流程分析 + +## 方法概述 + +`LoadData` 是 `clsBOMManager` 类的核心方法,负责从 Excel 工作表加载 BOM 数据并构建完整的层级数据结构。 + +## 方法签名 + +```vba +Public Sub LoadData(wsConfig As Worksheet, wsPlatform As Worksheet) +``` + +### 参数说明 + +| 参数 | 类型 | 说明 | +|------|------|------| +| `wsConfig` | Worksheet | [领料配置]工作表,包含类别层级和需要领料的物料 | +| `wsPlatform` | Worksheet | [平台配置清单]工作表,包含完整的物料信息 | + +## 整体流程图 + +```mermaid +flowchart TD + Start([开始 LoadData]) --> Step1[第一步: 加载物料基础信息] + Step1 --> Step2[第二步: 加载类别信息并关联物料] + Step2 --> Step3[第三步: 建立类别层级关系] + Step3 --> End([结束]) + + style Start fill:#e1f5e1 + style End fill:#ffe1e1 + style Step1 fill:#e1f0ff + style Step2 fill:#fff4e1 + style Step3 fill:#f0e1ff +``` + +## 详细流程分析 + +### 第一步:从平台配置清单加载所有物料的基础信息 + +```mermaid +flowchart TD + S1_Start([开始第一步]) --> S1_Init[初始化: 获取最后一行行号] + S1_Init --> S1_Loop{循环 i = 4 到 lastRow} + S1_Loop -->|i += 1| S1_Read[读取第 i 行数据] + S1_Read --> S1_Create[创建 clsMaterialItem 对象] + S1_Create --> S1_Assign[赋值: code, Name, Quantity, Condition] + S1_Assign --> S1_Check{code 是否非空?} + S1_Check -->|是| S1_Add[添加到 dictAllMaterials
键: code, 值: mat] + S1_Check -->|否| S1_Next[跳过] + S1_Add --> S1_Next + S1_Next --> S1_Loop + S1_Loop -->|i > lastRow| S1_End([第一步完成]) + + style S1_Start fill:#e1f5e1 + style S1_End fill:#ffe1e1 + style S1_Add fill:#c8e6c9 + style S1_Check fill:#fff9c4 +``` + +**数据来源**:[平台配置清单] 工作表 + +| 列 | 字段 | 说明 | +|----|------|------| +| C | code | 物料代号 | +| D | Name | 物料名称 | +| E | Quantity | 物料数量 | +| F | Condition | 选择条件 | + +**数据结构**: +``` +dictAllMaterials: Dictionary +├── "01011019001" → clsMaterialItem{code, Name, Quantity, Condition} +├── "01081013833" → clsMaterialItem{...} +└── ... +``` + +**关键代码**: +```vba +lastRow = wsPlatform.Cells(wsPlatform.Rows.Count, "C").End(xlUp).row +For i = 4 To lastRow + Set mat = New clsMaterialItem + mat.code = Trim(wsPlatform.Cells(i, "C").value & "") + mat.Name = Trim(wsPlatform.Cells(i, "D").value & "") + mat.Quantity = CDbl(wsPlatform.Cells(i, "E").value) + mat.Condition = Trim(wsPlatform.Cells(i, "F").value & "") + + If mat.code <> "" Then + Set dictAllMaterials(mat.code) = mat + End If +Next i +``` + +--- + +### 第二步:从领料配置加载类别信息并关联物料 + +```mermaid +flowchart TD + S2_Start([开始第二步]) --> S2_Init[初始化: 获取最后一行行号] + S2_Init --> S2_Loop{循环 i = 2 到 lastRow} + S2_Loop -->|i += 1| S2_Read[读取第 i 行数据
code, catName, parentCatName] + S2_Read --> S2_CheckCode{code 是否为空?} + S2_CheckCode -->|是| S2_NextRow[跳到下一行] + S2_CheckCode -->|否| S2_CheckCat{类别是否已存在?} + S2_CheckCat -->|否| S2_CreateCat[创建新的 clsCategory 对象
设置 categoryName 和 ParentCategoryName
添加到 dictCategories] + S2_CheckCat -->|是| S2_Exists[类别已存在] + S2_CreateCat --> S2_CheckMat{物料在
dictAllMaterials?} + S2_Exists --> S2_CheckMat + S2_CheckMat -->|是| S2_UpdateMat[更新物料信息:
mat.Category = catName
mat.ParentCategory = parentCatName
添加到类别 materials 集合] + S2_CheckMat -->|否| S2_SkipMat[物料不在库中,跳过] + S2_UpdateMat --> S2_NextRow + S2_SkipMat --> S2_NextRow + S2_NextRow --> S2_Loop + S2_Loop -->|i > lastRow| S2_End([第二步完成]) + + style S2_Start fill:#e1f5e1 + style S2_End fill:#ffe1e1 + style S2_CreateCat fill:#bbdefb + style S2_UpdateMat fill:#c8e6c9 + style S2_CheckCat fill:#fff9c4 + style S2_CheckMat fill:#fff9c4 +``` + +**数据来源**:[领料配置] 工作表 + +| 列 | 字段 | 说明 | +|----|------|------| +| A | code | 物料代号 | +| C | catName | 类别名称 | +| D | parentCatName | 上层类别名称 | + +**数据结构**: +``` +dictCategories: Dictionary +├── "表壳" → clsCategory{categoryName, materials[], SubCategories[]} +├── "部件" → clsCategory{...} +└── ... +``` + +**关键代码**: +```vba +lastRow = wsConfig.Cells(wsConfig.Rows.Count, "A").End(xlUp).row +For i = 2 To lastRow + code = Trim(wsConfig.Cells(i, "A").value & "") + catName = Trim(wsConfig.Cells(i, "C").value & "") + parentCatName = Trim(wsConfig.Cells(i, "D").value & "") + + If code = "" Then GoTo NextRow + + If Not dictCategories.Exists(catName) Then + Set cat = New clsCategory + cat.categoryName = catName + cat.ParentCategoryName = parentCatName + Set dictCategories(catName) = cat + End If + + If dictAllMaterials.Exists(code) Then + Set mat = dictAllMaterials(code) + mat.Category = catName + mat.ParentCategory = parentCatName + dictCategories(catName).AddMaterial mat + End If +Next i +``` + +**业务逻辑说明**: +- 只有出现在 [领料配置] 中的物料才会被添加到类别中 +- 未在 [领料配置] 中的物料表示不需要领料 + +--- + +### 第三步:建立类别层级关系 + +```mermaid +flowchart TD + S3_Start([开始第三步]) --> S3_Loop{遍历 dictCategories
所有键} + S3_Loop -->|下一个键| S3_GetCat[获取类别对象 cat] + S3_GetCat --> S3_CheckParent{ParentCategoryName
是否为空?} + S3_CheckParent -->|否, 有父类别| S3_ParentExists{父类别
存在?} + S3_CheckParent -->|是, 无父类别| S3_AddRoot[添加到 rootCategories
作为根类别] + S3_ParentExists -->|是| S3_AddSub[添加到父类别的
SubCategories 集合] + S3_ParentExists -->|否| S3_Orphan[父类别不存在
跳过建立关系] + S3_AddRoot --> S3_Next + S3_AddSub --> S3_Next + S3_Orphan --> S3_Next + S3_Next --> S3_Loop + S3_Loop -->|遍历完成| S3_End([第三步完成]) + + style S3_Start fill:#e1f5e1 + style S3_End fill:#ffe1e1 + style S3_AddRoot fill:#ffccbc + style S3_AddSub fill:#b2dfdb +``` + +**数据结构**: +``` +rootCategories: Collection +├── "表壳" (根类别) +├── "部件" (根类别) +│ └── SubCategories: +│ ├── "接头" (子类别) +│ └── "弹性元件" (子类别) +└── "机芯" (根类别) +``` + +**关键代码**: +```vba +For Each key In dictCategories.Keys + Set cat = dictCategories(key) + If cat.ParentCategoryName <> "" Then + If dictCategories.Exists(cat.ParentCategoryName) Then + Set parentCat = dictCategories(cat.ParentCategoryName) + parentCat.AddSubCategory cat + End If + Else + rootCategories.Add cat, cat.categoryName + End If +Next key +``` + +**层级关系构建逻辑**: +1. 遍历所有类别 +2. 如果类别有父类别 → 建立父子关系(调用父类别的 `AddSubCategory` 方法) +3. 如果类别无父类别 → 作为根类别,添加到 `rootCategories` + +--- + +## 数据结构总结 + +### 类的私有成员变量 + +```mermaid +classDiagram + class clsBOMManager { + -dictCategories: Dictionary + -dictAllMaterials: Dictionary + -rootCategories: Collection + +LoadData(wsConfig, wsPlatform) + +GetRootCategories() Collection + +GetCategory(categoryName) clsCategory + } + + class clsCategory { + +categoryName: String + +ParentCategoryName: String + +materials: Collection + +SubCategories: Collection + +AddMaterial(mat) + +AddSubCategory(cat) + +HasSubCategories: Boolean + } + + class clsMaterialItem { + +code: String + +Name: String + +Quantity: Double + +Condition: String + +Category: String + +ParentCategory: String + } + + clsBOMManager "1" --> "*" clsCategory : 管理 + clsCategory "1" --> "*" clsMaterialItem : 包含 + clsCategory "1" --> "*" clsCategory : 父子关系 +``` + +### 三个核心数据容器 + +| 数据容器 | 类型 | 键/索引 | 值 | 用途 | +|---------|------|---------|-----|------| +| `dictAllMaterials` | Dictionary | 物料代号 (String) | clsMaterialItem | 快速查找任意物料的完整信息 | +| `dictCategories` | Dictionary | 类别名称 (String) | clsCategory | 快速查找任意类别 | +| `rootCategories` | Collection | 索引 (Long) | clsCategory | 遍历完整的类别树结构 | + +--- + +## 流程时序图 + +```mermaid +sequenceDiagram + participant Caller as 调用者 + participant LoadData as LoadData方法 + participant WSPlatform as [平台配置清单] + participant WSConfig as [领料配置] + participant DictMat as dictAllMaterials + participant DictCat as dictCategories + participant RootCats as rootCategories + + Caller->>LoadData: LoadData(wsConfig, wsPlatform) + + Note over LoadData, WSPlatform: 第一步: 加载物料库 + LoadData->>WSPlatform: 读取第4-末行, C-F列 + WSPlatform-->>LoadData: 返回物料数据 + loop 每一行物料 + LoadData->>DictMat: 添加物料 (代号→对象) + end + + Note over LoadData, WSConfig: 第二步: 建立类别与物料关联 + LoadData->>WSConfig: 读取第2-末行, A/C/D列 + WSConfig-->>LoadData: 返回类别配置 + loop 每一行配置 + LoadData->>DictCat: 类别存在? + alt 类别不存在 + LoadData->>DictCat: 创建新类别 + end + LoadData->>DictMat: 查找物料信息 + alt 物料存在 + LoadData->>DictCat: 添加物料到类别 + end + end + + Note over LoadData, RootCats: 第三步: 构建层级树 + loop 遍历所有类别 + LoadData->>DictCat: 获取类别 + alt 有父类别 + LoadData->>DictCat: 添加到父类别的SubCategories + else 无父类别 + LoadData->>RootCats: 添加为根类别 + end + end + + LoadData-->>Caller: 完成 +``` + +--- + +## 重要业务规则 + +### 1. 物料筛选规则 +- ✅ 在 [领料配置] 中的物料 → **需要领料**,会被添加到类别中 +- ❌ 不在 [领料配置] 中的物料 → **不需要领料**,仅在 `dictAllMaterials` 中 + +### 2. 类别层级规则 +- 根类别:`ParentCategoryName` 为空字符串 `""` +- 子类别:`ParentCategoryName` 指向父类别名称 +- 层级深度:无限制(支持任意深度的树形结构) + +### 3. 数据一致性 +- 所有物料必须先在 [平台配置清单] 中定义 +- [领料配置] 中的物料代号必须在 `dictAllMaterials` 中存在 +- 如果不存在,该物料会被跳过(不会报错) + +--- + +## 使用示例 + +### 调用 LoadData + +```vba +Dim bomMgr As New clsBOMManager +Dim wsConfig As Worksheet +Dim wsPlatform As Worksheet + +Set wsConfig = ThisWorkbook.Worksheets("领料配置") +Set wsPlatform = ThisWorkbook.Worksheets("平台配置清单") + +' 加载数据 +Call bomMgr.LoadData(wsConfig, wsPlatform) + +' 获取根类别 +Dim rootCats As Collection +Set rootCats = bomMgr.GetRootCategories() + +' 遍历所有根类别 +Dim i As Long +For i = 1 To rootCats.Count + Debug.Print "根类别: " & rootCats(i).categoryName +Next i +``` + +--- + +## 执行后的数据结构示例 + +假设加载后的数据结构如下: + +``` +dictAllMaterials: +{ + "01091004312" → {code: "01091004312", Name: "表壳(本色)", Quantity: 1, Condition: ""}, + "01011019001" → {code: "01011019001", Name: "低压接头部件", Quantity: 1, Condition: "lcfw=M02"}, + "01081013833" → {code: "01081013833", Name: "径向低压接头", Quantity: 1, Condition: "gclj=Z12"} +} + +dictCategories: +{ + "表壳" → {categoryName: "表壳", ParentCategoryName: "", materials: [01091004312], SubCategories: []}, + "部件" → {categoryName: "部件", ParentCategoryName: "", materials: [01011019001], SubCategories: ["接头", "弹性元件"]}, + "接头" → {categoryName: "接头", ParentCategoryName: "部件", materials: [01081013833], SubCategories: []} +} + +rootCategories: +[ + "表壳" (clsCategory), + "部件" (clsCategory), + "机芯" (clsCategory) +] +``` + +--- + +## 错误处理 + +LoadData 方法本身不包含显式的错误处理(`On Error`),依赖以下机制: + +1. **空值处理**:使用 `& ""` 确保字符串转换不会失败 +2. **类型转换**:使用 `CDbl()` 时没有错误处理,假设数据格式正确 +3. **跳过机制**:物料代号为空时,使用 `GoTo NextRow` 跳过 +4. **存在性检查**:使用 `Dictionary.Exists()` 避免键不存在错误 + +--- + +## 相关方法 + +LoadData 执行后,可以使用以下方法访问数据: + +| 方法 | 说明 | +|------|------| +| `GetRootCategories()` | 获取所有顶层类别 | +| `GetCategory(categoryName)` | 根据名称获取类别对象 | +| `GetMaterialsByModel()` | 根据型号获取物料 | +| `GetValidMaterialsByModel()` | 获取物料并检查完整性 | +| `PrintCategoryTree()` | 打印类别树(调试用) | + +--- + +## 总结 + +`LoadData` 方法通过三个阶段构建完整的 BOM 数据结构: + +1. **数据收集**:从 [平台配置清单] 收集所有物料基础信息 +2. **数据关联**:从 [领料配置] 建立类别与物料的关联 +3. **结构构建**:构建类别的树形层级关系 + +最终形成的数据结构支持: +- 快速按代号查找物料 +- 快速按类别查找物料 +- 遍历完整的类别树 +- 支持父类别/子类别的领料逻辑 diff --git a/VBA/clsBOMManager使用说明.md b/reference_docs/clsBOMManager使用说明.md similarity index 100% rename from VBA/clsBOMManager使用说明.md rename to reference_docs/clsBOMManager使用说明.md diff --git a/VBA/combined_output.md b/reference_docs/combined_output.md similarity index 100% rename from VBA/combined_output.md rename to reference_docs/combined_output.md diff --git a/型号解析与物料匹配系统 - 使用说明.md b/reference_docs/型号解析与物料匹配系统 - 使用说明.md similarity index 100% rename from 型号解析与物料匹配系统 - 使用说明.md rename to reference_docs/型号解析与物料匹配系统 - 使用说明.md diff --git a/布莱迪公司压力表产品选型大表.md b/reference_docs/布莱迪公司压力表产品选型大表.md similarity index 100% rename from 布莱迪公司压力表产品选型大表.md rename to reference_docs/布莱迪公司压力表产品选型大表.md diff --git a/新增条件提取计划.md b/reference_docs/新增条件提取计划.md similarity index 100% rename from 新增条件提取计划.md rename to reference_docs/新增条件提取计划.md