# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview AutoBOM is an Excel-based Bill of Materials (BOM) management system for pressure product manufacturing. The project includes TWO functional modules: 1. **BOM Configuration System** (VBA/) - Parses conditional logic rules and generates categorized BOM configurations from Excel spreadsheets based on "平台配置清单" worksheet 2. **BOM Extraction System** (VBA_BOMConverter/) - Parses product model strings and automatically extracts matching materials from BOM库.xlsx based on "产品型号" worksheet ## Architecture ### BOM Configuration System (VBA/Modules/) The BOM Configuration system follows a modular architecture with clear separation of concerns: - **M01_Main.bas** - Entry point and orchestration. Run `RunBOMConversion()` to execute the full workflow. - **M02_DataIO.bas** - Data input/output operations. Reads source data from "平台配置清单" worksheet and generates categorized output workbooks. - **M03_Logic.bas** - Core recursive parser for conditional expressions. Handles logical operators (AND/OR), nested parentheses, and key=value/key!=val conditions. Implements Cartesian products for set operations. - **M04_Config.bas** - Column mapping and header priorities. Defines source data columns (CODE, NAME, QTY, CONDITION, CATEGORY) and standard ordering for output. - **M05_PreProcessor.bas** - Preprocessing module for condition transformation. Handles category-specific preprocessing: "接头" (azxs+lcfw mapping, OR merging, parentheses simplification), "部件" (azxs mapping only, OR merging, parentheses simplification). Uses mapping data from "对照表" worksheet. - **M99_TestRunner.bas** - Unit testing framework. Run `RunAllTests()` in VBA Immediate window to execute tests. ### BOM Extraction System (VBA_BOMConverter/Modules/) The BOM Extraction system follows a modular architecture with clear separation of concerns: - **M09_BOMExtractor.bas** - Main orchestration and entry point. Run `RunBOMExtraction()` to execute the full workflow. Implements two-phase validation (collect → validate) and generates output worksheets. - **M06_ModelParser.bas** - Product model string parsing. Extracts parameters from full model strings (e.g., `YTHN-100.A0.531.G123.M04.Y3|BP-088.2312.B09.0A3`). Applies value mapping via M06A_Mapper. - **M06A_Mapper.bas** - Value mapping module. Maps azxs and lcfw parameters to their descriptive values from "对照表" worksheet. Returns dual-value format (raw,mapped) for flexible matching. - **M07_BOMMatcher.bas** - BOM library matching. Matches extracted parameters against BOM库.xlsx worksheets using parameter-based rules (empty cells = wildcard, "!=" prefix = negative match, fjgn field = substring matching, dual-value matching for mapped parameters). - **M08_ComponentProcessor.bas** - Special handling for "部件" (component) materials. Handles component inventory logic (component vs sub-components selection). - **M06B_TestRunner.bas** - Unit testing framework for BOM Extraction system. Run tests in VBA Immediate window. ### Class Module - **clsErrorLogger.cls** - Error and warning handling. Tracks conflicts, parsing failures, and provides detailed context. Supports both errors (blocking) and warnings (non-blocking) with color-coded reporting. ### Data Flow **BOM Configuration System Flow**: ``` Excel "平台配置清单" → M01_Main → M02_DataIO.LoadSourceData() → M05_PreProcessor.PreprocessCondition() → M03_Logic.ParseRule() → Category Dictionary → M02_DataIO.CreateOutputWorkbook() → New Excel Workbook + Error Report ``` **BOM Extraction System Flow**: ``` "产品型号" worksheet → M09_BOMExtractor.RunBOMExtraction() → M06A_Mapper.InitMapper() (load mapping table from "对照表" worksheet) → M06_ModelParser.ParseProductModel() → Extract raw parameters: azxs="A0", lcfw="M01" → M06A_Mapper.MapAzxs() / MapLcfw() → Return dual values: azxs="A0,径向", lcfw="M01,低压" → M07_BOMMatcher.MatchBOMRecord() → EvaluateCellCondition() supports dual-value matching → Match if BOM库 contains "A0" OR "径向" → M08_ComponentProcessor.ProcessComponentRecord() (special component handling if applicable) → Two-phase validation (collect all matches → validate with cross-worksheet rules) → "BOM提取结果" worksheet + "错误报告" worksheet ``` ## Key Concepts --- ## BOM Configuration System (VBA/) ### Preprocessing (M05_PreProcessor) Before parsing conditions, the system applies category-specific preprocessing: **Supported Categories**: | Category | azxs Mapping | lcfw Mapping | OR Merging | Parentheses Simplification | |----------|-------------|--------------|------------|----------------------------| | 接头 | ✓ | ✓ | ✓ | ✓ | | 部件 | ✓ | ✗ | ✓ | ✓ | | Other | ✗ | ✗ | ✗ | ✗ | **Value Mapping**: - **azxs** (安装形式): Maps codes to descriptive values - A0, AT, AH → 径向 - B0, BT, BZ, BH → 下轴向 - Z0, ZT, ZZ, ZH → 中轴向 - **lcfw** (量程范围): Maps range codes to categories (接头 category only) - M01-M11 → 低压 - M12-M16 → 高压 **OR Condition Merging**: - Duplicate OR conditions are automatically merged - Example: `azxs=径向 OR azxs=径向` → `azxs=径向` - Different values preserve OR structure: `lcfw=低压 OR lcfw=高压` **Parentheses Handling**: - Simplified single-value expressions: `(azxs=A0 OR azxs=AT)` → `azxs=径向` - Preserves parentheses when needed: `(lcfw=M01 OR lcfw=M15)` → `(lcfw=低压 OR lcfw=高压)` Mapping data is loaded from "对照表" worksheet (columns A:B for lcfw, D:E for azxs). ### Conditional Logic Syntax (M03_Logic) Conditions use a specific syntax for product selection: - **Atoms**: `key=value` or `key!=value` (e.g., `gclj=M20`, `jycz=1`) - **AND**: Cartesian product of sets (e.g., `gclj=M20 AND jycz=1`) - **OR**: Union of sets (e.g., `azxs=A0 OR azxs=AT`) - **Parentheses**: Nested grouping (e.g., `(azxs=A0 OR azxs=AT) AND jycz=1`) Example: `gclj=M20 AND jycz=1 AND lcfw=M01 AND (azxs=A0 OR azxs=AT OR azxs=AH)` ### Column Mapping (M04_Config) Source data must have columns in this order: - Column C (3): CODE (代号) - Column D (4): NAME (名称) - Column E (5): QTY (数量) - Column F (6): CONDITION (选择条件) - Column H (8): CATEGORY (类别) Data starts from row 4. ### Category-Based Output Results are automatically organized by category (部件, 接头, 弹性元件, etc.). Each category gets a separate worksheet in the output workbook with columns dynamically ordered based on detected configuration keys. --- ## BOM Extraction System (VBA_BOMConverter/) ### Model String Structure (M06_ModelParser) Product models follow a structured format that the parser can extract parameters from: **Full Model**: `[表头]|[表盘]|[附件]|[法兰隔膜]` **Table Header Format**: `[型号]-[公称外径].[安装形式].[壳体形式].[过程连接&接液材质].[量程范围].[仪表特性]` **Example**: `YTHN-100.A0.531.G123.M04.Y3|BP-088.2312.B09.0A3` - Table header: `YTHN-100.A0.531.G123.M04.Y3` - Parameters extracted: - `xh` = YTHN (型号) - `gcwj` = 100 (公称外径) - `azxs` = A0 (安装形式) - `bkxs` = 531 (表壳形式) - `gclj` = G12 (过程连接) - `jycz` = 3 (接液材质) - `lcfw` = M04 (量程范围) - `fjgn` = Y3 (附加功能) **Parsing Logic**: - Only processes table header portion (before first `|`) - Segments are split by `.` delimiter - `gclj` and `jycz` are extracted from single segment (last char is `jycz`) - `fjgn` combines all segments from position 5 onwards with comma separator ### Value Mapping (M06A_Mapper) After parsing raw parameter values, the system applies value mapping from "对照表" worksheet: **Dual-Value Format**: - Parameters are stored as "raw,mapped" to support flexible matching - Example: `azxs="A0,径向"` means the parameter can match either "A0" or "径向" - Example: `lcfw="M01,低压"` means the parameter can match either "M01" or "低压" **Mapping Table Configuration** (M04_Config): - `MAPPING_SHEET_NAME` = "对照表" - `MAPPING_COL_LCFW_KEY` = 1 (A列) - lcfw raw values - `MAPPING_COL_LCFW_VAL` = 2 (B列) - lcfw mapped values - `MAPPING_COL_AZXS_KEY` = 4 (D列) - azxs raw values - `MAPPING_COL_AZXS_VAL` = 5 (E列) - azxs mapped values - `MAPPING_START_ROW` = 3 **Graceful Degradation**: - If "对照表" worksheet is not found, system logs a warning and uses raw values only - If a value is not found in mapping table, only the raw value is used (no error) **Example Mapping Data**: | Row | A列 (lcfw key) | B列 (lcfw val) | D列 (azxs key) | E列 (azxs val) | |-----|----------------|----------------|----------------|----------------| | 3 | M01 | 低压 | A0 | 径向 | | 4 | M12 | 高压 | AT | 径向 | | 5 | - | - | B0 | 下轴向 | ### BOM Matching Rules (M07_BOMMatcher) The system matches extracted parameters against BOM库.xlsx worksheets using these rules: **Cell Matching Rules**: - **Empty cell**: Wildcard - matches all values - **"!=" prefix**: Negative match - matches when parameter ≠ value (e.g., `!=A0`) - **fjgn field**: Substring matching - matches when fjgn list contains cell value (InStr check) - **Dual-value parameters**: Matches if ANY value matches (e.g., `azxs="A0,径向"` matches both `azxs=A0` and `azxs=径向`) - **Normal values**: Exact match - parameter must equal cell value **Logic**: AND across all parameters - all conditions must be satisfied **Examples**: 1. **Dual-value matching**: - Parameter: `azxs="A0,径向"` - BOM库 has `azxs=径向` → MATCH (because "径向" is in the parameter) - BOM库 has `azxs=A0` → MATCH (because "A0" is in the parameter) - BOM库 has `azxs=AT` → NO MATCH 2. **Standard matching**: - BOM库 row has `azxs=A0`, `bkxs=`, `gclj=G12`, `fjgn=N1` - Matches: `azxs=A0,径向`, `bkxs=531`, `gclj=G12`, `fjgn=N1,N2` - Reason: `azxs` contains "A0", `bkxs` is empty (wildcard), `gclj` matches exactly, `fjgn` contains "N1" ### Component Special Handling (M08_ComponentProcessor) "部件" (component) materials contain three types of materials in one record: **Record Structure**: 1. Component material itself (部件) 2. Joint material (接头) - sub-component 1 3. Elastic element material (弹性元件) - sub-component 2 **Selection Strategy**: - **Inventory sufficient** → Return component material (1 item) - **Inventory insufficient** → Return sub-components (1 joint + 1 elastic element) **Validation Rules**: - Valid: 1 component OR 1 joint + 1 elastic element - Invalid: Any other combination (e.g., component + joint together, only joint, only element, multiple components) **Note**: Inventory checking interface is reserved for future ERP integration. Current version always returns inventory sufficient. ### Two-Phase Validation (M09_BOMExtractor) The system uses two-phase validation to enable cross-worksheet validation: **Phase 1: Collection** - Iterate through all BOM库 worksheets - Collect match results WITHOUT recording errors - Store results for each worksheet: success, rowCount, rowNums, materials **Phase 2: Validation** - Validate all collected results together - Apply cross-worksheet rules (e.g., component/joint/element exclusivity) - Distinguish between **errors** (blocking) and **warnings** (non-blocking) **Cross-Worksheet Validation Rules**: 1. **Component sheet returns component** → Ignore independent joint/element worksheets (warning) 2. **Component sheet returns sub-components** → Ignore independent joint/element worksheets (warning) 3. **Component sheet has no match** → Use independent joint/element worksheets 4. **Non-special worksheets** → Must match exactly 1 record **Error vs Warning**: - **Error**: Blocking issues (0 matches, 2+ matches, invalid combinations) - **Warning**: Non-blocking issues (conflicting matches that were resolved) ## Development Commands ### Running BOM Configuration System 1. Open `YTHN-100.xlsm` in Excel 2. Ensure "平台配置清单" worksheet exists with proper data 3. Run `M01_Main.RunBOMConversion()` or execute from the Excel interface **Output**: New Excel workbook with categorized BOM data + error report ### Running BOM Extraction System 1. Open the main Excel workbook (e.g., `YTHN-100.xlsm`) 2. Ensure "产品型号" worksheet exists with product model data 3. Ensure `BOM库.xlsx` is in the same directory as the main workbook 4. (Optional) Ensure "对照表" worksheet exists for azxs/lcfw value mapping 5. Run `M09_BOMExtractor.RunBOMExtraction()` or execute from the Excel interface **Output**: - "BOM提取结果" worksheet - Contains extracted materials with parameters - "错误报告_[timestamp]" worksheet - Generated only if errors/warnings exist ### Running Tests In Excel VBA Immediate Window (Ctrl+G): **For BOM Configuration System (M99_TestRunner)**: ``` RunAllTests ``` This runs unit tests for: - Simple atom parsing (`key=value`) - AND operations with Cartesian products - OR operations with union operations - Nested parentheses handling - Logic conflict detection - **Preprocessing tests** (Test_PP_01 to Test_PP_12): - azxs mapping load (12 values) - lcfw mapping load (M01-M16) - Value replacement - OR condition merging - Full integration with M03_Logic - Non-"接头"/"部件" category handling - Unmapped value handling - "部件" category azxs mapping (PP_09) - "部件" category lcfw unchanged (PP_10) - "部件" category OR merging (PP_11) - "部件" category parentheses simplification (PP_12) **For BOM Extraction System (M06B_TestRunner)**: ``` RunAllTests ``` This runs unit tests for: - M06_ModelParser tests (model string parsing) - M07_BOMMatcher tests (BOM library matching) - M08_ComponentProcessor tests (component handling) - M09_BOMExtractor tests (full extraction workflow) ### Python Skills (Claude Code Integration) The project includes custom skills in `.claude/skills/`: - **excel-to-markdown**: Convert Excel files to Markdown tables ```bash python3 .claude/skills/excel-to-markdown/scripts/excel_to_markdown.py ``` - **mermaid-diagrams**: Generate architecture diagrams using Mermaid syntax ## Configuration ### System Constants (M04_Config) **File Configuration**: - `BOMLIB_FILENAME` = "BOM库.xlsx" - BOM library file name - `OUTPUT_SHEET_NAME` = "BOM提取结果" - Output worksheet name - `BOMLIB_START_ROW` = 2 - BOM库 data starts from row 2 (row 1 is header) **Mapping Table Configuration**: - `MAPPING_SHEET_NAME` = "对照表" - Mapping table worksheet name - `MAPPING_COL_LCFW_KEY` = 1 - Column A for lcfw raw values - `MAPPING_COL_LCFW_VAL` = 2 - Column B for lcfw mapped values - `MAPPING_COL_AZXS_KEY` = 4 - Column D for azxs raw values - `MAPPING_COL_AZXS_VAL` = 5 - Column E for azxs mapped values - `MAPPING_START_ROW` = 3 - Mapping data starts from row 3 **Input Column Configuration**: - `INPUT_COL_MODEL` = "型号" - `INPUT_COL_PRODUCT_MODEL` = "产品型号" **BOM库 Worksheet Names**: - `BOMLIB_SHEET_JOINT` = "接头" - `BOMLIB_SHEET_ELEMENT` = "弹性元件" - `BOMLIB_SHEET_MOVEMENT` = "机芯" - `BOMLIB_SHEET_COMPONENT` = "部件" - `BOMLIB_SHEET_EDGE` = "边" **BOM库 Column Names**: - `BOMLIB_COL_NAME` = "名称" - `BOMLIB_COL_CODE` = "编码" - `BOMLIB_COL_QTY` = "数量" - `BOMLIB_COL_JOINT_NAME` = "接头名称" - `BOMLIB_COL_JOINT_CODE` = "接头编码" - `BOMLIB_COL_JOINT_QTY` = "接头数量" - `BOMLIB_COL_ELEMENT_NAME` = "弹性元件名称" - `BOMLIB_COL_ELEMENT_CODE` = "弹性元件编码" - `BOMLIB_COL_ELEMENT_QTY` = "弹性元件数量" **Model Parsing Constants**: - `MODEL_SEPARATOR_PIPELINE` = "|" - `MODEL_SEPARATOR_DOT` = "." - `MODEL_HEADER_MIN_SEGMENTS` = 6 ### Header Priority Ordering Output columns are sorted according to priority defined in `M04_Config.GetHeaderPriority()`: 1. azxs (安装形式) 2. bkxs (表壳形式) 3. gclj (过程连接) 4. jycz (介质材质) 5. lcdw (量程单位) 6. lcfw (量程范围) 7. fjgn (非公/耐震) 8. btcy (表头尺寸) 9. bp (表盘) 10. dskd (度视宽度) 11. nqlc (耐震连接) 12. bptx (表盘图形) 13. jddj (精度等级) 14. cpdm (产品代码) 15. tsjz (特殊基准) 16. tsyq (特殊要求) 17. bpts (特殊表盘) 18. kdxh (壳体型号) Unknown keys are assigned priority 999 and appear last. ## Git Workflow ### Branches - **Main branch**: `DEV_YTHN-100` - **Current branch**: `NEW_BOM` ### Claude Code Permissions Configured in `.claude/settings.local.json`: - Git operations: push, checkout, add - Python execution - Tree viewing and search utilities ### NTFY Notifications The repository uses NTFY for git push notifications. Repository name is extracted dynamically from `github.repository` in workflow files. ## File Structure ``` AutoBOM/ ├── VBA_BOMConverter/ │ ├── Modules/ │ │ ├── M01_Main.bas # BOM Configuration System - Entry point │ │ ├── M02_DataIO.bas # BOM Configuration System - Data I/O │ │ ├── M03_Logic.bas # BOM Configuration System - Conditional logic parser │ │ ├── M04_Config.bas # Shared - Constants and configuration │ │ ├── M05_PreProcessor.bas # BOM Configuration System - Preprocessing │ │ ├── M06_ModelParser.bas # BOM Extraction System - Model parsing │ │ ├── M06A_Mapper.bas # BOM Extraction System - Value mapping (NEW) │ │ ├── M06B_TestRunner.bas # BOM Extraction System - Unit tests │ │ ├── M07_BOMMatcher.bas # BOM Extraction System - BOM matching │ │ ├── M08_ComponentProcessor.bas # BOM Extraction System - Component handling │ │ ├── M09_BOMExtractor.bas # BOM Extraction System - Main orchestration │ │ └── M99_TestRunner.bas # BOM Configuration System - Unit tests │ └── ClassModules/ │ └── clsErrorLogger.cls # Shared - Error/warning logging ├── .claude/ │ └── skills/ # Claude Code integration skills ├── docs/ # Code-related documentation │ └── Test_PP_06_FullIntegration_流程详解.md ├── reference_docs/ # Business-related documentation and examples └── YTHN-100.xlsm/.xlsx # Main workbook files ``` ## Error Handling The system uses `clsErrorLogger` for comprehensive error and warning tracking: **Error vs Warning Distinction**: - **Errors**: Blocking issues that indicate failure (red highlighting in report) - Examples: No match found, multiple matches, invalid combinations - Properties: `HasErrors`, `pErrors.Count` - **Warnings**: Non-blocking issues (yellow highlighting in report) - Examples: Conflicting matches that were resolved, fallback scenarios - Properties: `HasWarnings`, `pWarnings.Count` - **HasIssues**: True if either errors or warnings exist **Error Recording**: ```vba ' Record error logger.Record rowIndex, sourceFunction, errorType, description, context ' Record warning logger.RecordWarning rowIndex, sourceFunction, warningType, description, context ``` **Error Report Output**: - Creates "错误报告_[timestamp]" worksheet - Color-coded rows: red for errors, yellow for warnings - Columns: Type, Row Number, Source Module, Error Type, Description, Context - Only generated if issues exist ## Important Notes ### BOM Configuration System - **Late Binding**: VBA modules use late binding (CreateObject) to avoid external reference dependencies - **Operator Precedence**: AND is processed before OR, parentheses override default precedence - **Recursive Parsing**: Nested expressions are handled recursively in M03_Logic - **Dynamic Columns**: Output workbooks detect and include only relevant configuration keys ### BOM Extraction System - **rowCount vs materials.count**: Critical distinction in BOM matching - `rowCount` = Number of worksheet rows matched in BOM库 - `materials.count` = Number of actual materials returned - These can differ when components fall back to sub-components (1 row → 2 materials) - **Performance Optimizations**: - Array-based processing instead of cell-by-cell operations - Header mapping cached for each worksheet - Progress updates every 10 models - Screen updating and calculation disabled during execution - **Two-Phase Matching**: Separates collection from validation to enable cross-worksheet validation rules that would be impossible with immediate error reporting - **Late Binding**: VBA modules use late binding (CreateObject) to avoid external reference dependencies - **Dynamic Columns**: Output workbooks detect and include only relevant configuration keys based on extracted parameters ## Documentation Guidelines ### Document Storage Policy When creating documentation for this project, follow these guidelines: **Code-Related Documentation** → Save in `docs/` directory: - Technical specifications - Algorithm explanations - Code flow diagrams - Test documentation - API/reference documentation for code modules - Implementation guides Examples: - `docs/Test_PP_06_FullIntegration_流程详解.md` ✓ - `docs/M03_Logic_Algorithm.md` ✓ - `docs/API_Reference.md` ✓ **Business-Related Documentation** → Save in `reference_docs/` directory: - Business requirements - User manuals - Product specifications - Industry standards - Configuration examples - Business process documentation Examples: - `reference_docs/BOM_Requirements.md` ✓ - `reference_docs/Product_Catalog.xlsx` ✓ - `reference_docs/User_Guide.pdf` ✓ **Decision Tree**: ``` Is it about code implementation or technical details? ├─ Yes → docs/ └─ No → Is it about business logic or user-facing content? ├─ Yes → reference_docs/ └─ No → Ask for clarification ``` **Note**: When in doubt, prefer `docs/` for technical content and `reference_docs/` for business content.