# 物控学习笔记 📚 > 物料控制(Material Control)学习笔记与最佳实践 --- ## 📖 目录 - [基础知识](#基础知识) - [Excel VBA 工具库](#excel-vba-工具库) - [库存管理](#库存管理) - [生产计划](#生产计划) - [数据分析](#数据分析) - [自动化脚本](#自动化脚本) - [案例研究](#案例研究) - [资源推荐](#资源推荐) --- ## 基础知识 ### 什么是物控? 物料控制(Material Control)是生产管理中的核心环节,主要负责: - 物料需求计划(MRP) - 库存管理与优化 - 采购计划制定 - 物料追溯与盘点 - 成本控制 ### 物控的核心指标 1. **库存周转率** = 年销售成本 / 平均库存 2. **库存天数** = 365 / 库存周转率 3. **缺料率** = 缺料次数 / 总领料次数 4. **呆滞料比例** = 呆滞料金额 / 总库存金额 5. **物料齐套率** = 齐套订单数 / 总订单数 ### 物控工作流程 ``` 1. 接收生产计划 ↓ 2. 计算物料需求(BOM展开) ↓ 3. 检查库存状态 ↓ 4. 制定采购计划 ↓ 5. 跟踪物料到货 ↓ 6. 物料发放与追溯 ↓ 7. 库存盘点与优化 ``` --- ## Excel VBA 工具库 ### 现有工具 本仓库包含以下 Excel VBA 物控工具: #### 1. **vba-mc-toolkit** ⭐ Excel VBA 物控小程序库 **功能模块**: - 物料需求计算 - 库存报表生成 - 采购订单管理 - 盘点表自动生成 - 呆滞料分析 **使用方法**: ```vba ' 导入工具库 Sub Import_MC_Toolkit() Workbooks.Open "vba-mc-toolkit.xlsm" Application.Run "Initialize_MC_System" End Sub ``` ### VBA 物控常用代码片段 #### 1. 自动计算安全库存 ```vba Function Calculate_Safety_Stock(avg_demand As Double, lead_time As Double, service_level As Double) As Double ' avg_demand: 平均日需求 ' lead_time: 采购提前期(天) ' service_level: 服务水平(0.95 = 95%) Dim z_score As Double Select Case service_level Case 0.90: z_score = 1.28 Case 0.95: z_score = 1.65 Case 0.98: z_score = 2.05 Case 0.99: z_score = 2.33 Case Else: z_score = 1.65 End Select Calculate_Safety_Stock = avg_demand * lead_time * z_score End Function ``` #### 2. 库存预警 ```vba Sub Inventory_Alert() Dim ws As Worksheet Set ws = ThisWorkbook.Sheets("库存") Dim last_row As Long last_row = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row For i = 2 To last_row Dim current_qty As Double Dim min_qty As Double Dim max_qty As Double current_qty = ws.Cells(i, "D").Value ' 当前库存 min_qty = ws.Cells(i, "E").Value ' 最低库存 max_qty = ws.Cells(i, "F").Value ' 最高库存 If current_qty < min_qty Then ws.Cells(i, "G").Value = "⚠️ 需补货" ws.Cells(i, "G").Interior.Color = RGB(255, 200, 200) ElseIf current_qty > max_qty Then ws.Cells(i, "G").Value = "📦 库存过高" ws.Cells(i, "G").Interior.Color = RGB(255, 255, 200) Else ws.Cells(i, "G").Value = "✅ 正常" ws.Cells(i, "G").Interior.Color = RGB(200, 255, 200) End If Next i End Sub ``` #### 3. 物料需求计算(MRP) ```vba Sub Calculate_MRP() Dim ws_bom As Worksheet, ws_inventory As Worksheet, ws_mrp As Worksheet Set ws_bom = ThisWorkbook.Sheets("BOM") Set ws_inventory = ThisWorkbook.Sheets("库存") Set ws_mrp = ThisWorkbook.Sheets("MRP") ' 清空 MRP 表 ws_mrp.Cells.Clear ' 设置表头 ws_mrp.Range("A1:F1").Value = Array("物料编码", "物料名称", "需求量", "库存量", "净需求", "建议采购") ' 计算逻辑 Dim last_row As Long last_row = ws_bom.Cells(ws_bom.Rows.Count, "A").End(xlUp).Row For i = 2 To last_row Dim part_no As String Dim qty_needed As Double Dim qty_in_stock As Double Dim net_qty As Double part_no = ws_bom.Cells(i, "A").Value qty_needed = ws_bom.Cells(i, "C").Value ' 查找库存 qty_in_stock = Application.WorksheetFunction.VLookup(part_no, ws_inventory.Range("A:D"), 4, False) net_qty = qty_needed - qty_in_stock If net_qty > 0 Then ws_mrp.Cells(i, 1).Value = part_no ws_mrp.Cells(i, 3).Value = qty_needed ws_mrp.Cells(i, 4).Value = qty_in_stock ws_mrp.Cells(i, 5).Value = net_qty ws_mrp.Cells(i, 6).Value = net_qty * 1.1 ' 建议采购量(含 10% 安全系数) End If Next i End Sub ``` #### 4. 盘点表生成 ```vba Sub Generate_Inventory_Count_Sheet() Dim ws As Worksheet Set ws = ThisWorkbook.Sheets.Add ws.Name = "盘点表_" & Format(Date, "yyyy-mm-dd") ' 设置表头 ws.Range("A1:H1").Value = Array("序号", "物料编码", "物料名称", "规格", "单位", "账面数量", "实盘数量", "差异") ws.Range("A1:H1").Font.Bold = True ' 从库存表复制数据 Dim ws_stock As Worksheet Set ws_stock = ThisWorkbook.Sheets("库存") Dim last_row As Long last_row = ws_stock.Cells(ws_stock.Rows.Count, "A").End(xlUp).Row For i = 2 To last_row ws.Cells(i, 1).Value = i - 1 ws.Cells(i, 2).Value = ws_stock.Cells(i, "A").Value ws.Cells(i, 3).Value = ws_stock.Cells(i, "B").Value ws.Cells(i, 4).Value = ws_stock.Cells(i, "C").Value ws.Cells(i, 5).Value = ws_stock.Cells(i, "G").Value ws.Cells(i, 6).Value = ws_stock.Cells(i, "D").Value Next i ' 格式化 ws.Columns("A:H").AutoFit ws.Range("H2:H" & last_row).Formula = "=F2-G2" MsgBox "盘点表生成完成!" End Sub ``` #### 5. 呆滞料分析 ```vba Sub Analyze_Stagnant_Inventory() Dim ws As Worksheet Set ws = ThisWorkbook.Sheets("库存") Dim last_row As Long last_row = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row ' 添加呆滞料标识列 ws.Cells(1, "I").Value = "呆滞状态" ws.Cells(1, "J").Value = "呆滞天数" For i = 2 To last_row Dim last_move_date As Date Dim days_stagnant As Long last_move_date = ws.Cells(i, "H").Value ' 最后移动日期 days_stagnant = Date - last_move_date ws.Cells(i, "J").Value = days_stagnant Select Case days_stagnant Case Is > 365 ws.Cells(i, "I").Value = "🔴 严重呆滞(>1年)" ws.Cells(i, "I").Interior.Color = RGB(255, 150, 150) Case Is > 180 ws.Cells(i, "I").Value = "🟡 中度呆滞(6-12月)" ws.Cells(i, "I").Interior.Color = RGB(255, 220, 150) Case Is > 90 ws.Cells(i, "I").Value = "⚠️ 轻度呆滞(3-6月)" ws.Cells(i, "I").Interior.Color = RGB(255, 255, 150) Case Else ws.Cells(i, "I").Value = "✅ 正常" ws.Cells(i, "I").Interior.Color = RGB(200, 255, 200) End Select Next i ' 统计 Dim stagnant_count As Long Dim stagnant_value As Double For i = 2 To last_row If ws.Cells(i, "J").Value > 90 Then stagnant_count = stagnant_count + 1 stagnant_value = stagnant_value + ws.Cells(i, "D").Value * ws.Cells(i, "E").Value End If Next i MsgBox "呆滞料分析完成!" & vbCrLf & _ "呆滞物料数量:" & stagnant_count & vbCrLf & _ "呆滞料金额:$" & Format(stagnant_value, "#,##0.00") End Sub ``` --- ## 库存管理 ### 库存分类方法 #### ABC 分析法 - **A 类**:价值占比 70-80%,数量占比 10-20% → 重点管理,高频盘点 - **B 类**:价值占比 15-25%,数量占比 20-30% → 中等管理,中频盘点 - **C 类**:价值占比 5-10%,数量占比 50-70% → 简化管理,低频盘点 #### VED 分类法(关键性) - **V(Vital)**:关键物料,缺料导致停产 - **E(Essential)**:重要物料,缺料影响生产 - **D(Desirable)**:一般物料,缺料影响较小 ### 库存优化策略 1. **安全库存计算** ``` 安全库存 = 平均日需求 × 安全天数 × 波动系数 其中: - 安全天数 = 采购提前期 + 缓冲天数 - 波动系数 = 1.2 ~ 1.5(根据历史数据调整) ``` 2. **订货点(ROP)** ``` 订货点 = 平均日需求 × 采购提前期 + 安全库存 ``` 3. **经济订货量(EOQ)** ``` EOQ = √(2 × 年需求量 × 单次订货成本 / 单位持有成本) ``` ### 库存盘点方法 | 盘点方式 | 适用场景 | 优点 | 缺点 | |---------|---------|------|------| | 全面盘点 | 年度/半年度 | 准确性高 | 耗时耗力 | | 循环盘点 | 日常管理 | 持续监控 | 覆盖不全 | | ABC 分类盘点 | A类物料高频 | 重点突出 | B/C类可能遗漏 | | 随机抽样盘点 | 月度抽查 | 效率高 | 准确性较低 | --- ## 生产计划 ### MRP 计算逻辑 ``` 毛需求 = 生产计划 × BOM 用量 净需求 = 毛需求 - 现有库存 - 在途库存 + 安全库存 建议采购量 = 净需求 × 订货倍数(MOQ) ``` ### 生产排程原则 1. **优先级规则** - 交期优先(EDD) - 最短加工时间(SPT) - 关键比率(CR) 2. **产能平衡** ``` 产能负荷 = 标准工时 × 数量 / 有效工时 负荷率 = 产能负荷 / 总产能 ``` 3. **瓶颈管理** - 识别瓶颈工序 - 瓶颈前缓冲库存 - 瓶颈后拉式生产 --- ## 数据分析 ### 关键指标仪表板 ```python # Python 物控数据分析示例 import pandas as pd import matplotlib.pyplot as plt # 1. 库存周转率分析 def inventory_turnover_analysis(df): """ df: 包含 '物料编码', '期初库存', '期末库存', '销售成本' 的 DataFrame """ df['平均库存'] = (df['期初库存'] + df['期末库存']) / 2 df['库存周转率'] = df['销售成本'] / df['平均库存'] df['库存天数'] = 365 / df['库存周转率'] return df # 2. 呆滞料分析 def stagnant_inventory_analysis(df, days_threshold=90): """ 分析呆滞料 """ df['呆滞天数'] = (pd.Timestamp.now() - df['最后移动日期']).dt.days df['呆滞状态'] = pd.cut(df['呆滞天数'], bins=[0, 30, 90, 180, 365, float('inf')], labels=['正常', '预警', '轻度呆滞', '中度呆滞', '严重呆滞']) return df # 3. 库存结构分析 def inventory_structure_analysis(df): """ ABC 分类 """ df['物料价值'] = df['库存数量'] * df['单价'] df_sorted = df.sort_values('物料价值', ascending=False) df_sorted['累计价值占比'] = df_sorted['物料价值'].cumsum() / df_sorted['物料价值'].sum() def abc_class(cum_ratio): if cum_ratio <= 0.8: return 'A' elif cum_ratio <= 0.95: return 'B' else: return 'C' df_sorted['ABC分类'] = df_sorted['累计价值占比'].apply(abc_class) return df_sorted ``` ### 可视化仪表板 ```python # 库存仪表板 def create_inventory_dashboard(df): fig, axes = plt.subplots(2, 2, figsize=(15, 10)) # 1. 库存结构饼图 abc_counts = df['ABC分类'].value_counts() axes[0, 0].pie(abc_counts.values, labels=abc_counts.index, autopct='%1.1f%%') axes[0, 0].set_title('ABC 库存结构') # 2. 库存周转率柱状图 top_items = df.nlargest(10, '库存周转率') axes[0, 1].bar(top_items['物料编码'], top_items['库存周转率']) axes[0, 1].set_title('Top 10 库存周转率') axes[0, 1].tick_params(axis='x', rotation=45) # 3. 呆滞料分布 stagnant_counts = df['呆滞状态'].value_counts() axes[1, 0].bar(stagnant_counts.index, stagnant_counts.values) axes[1, 0].set_title('呆滞料分布') # 4. 库存价值分布 axes[1, 1].hist(df['物料价值'], bins=20, edgecolor='black') axes[1, 1].set_title('库存价值分布') axes[1, 1].set_xlabel('物料价值') axes[1, 1].set_ylabel('频次') plt.tight_layout() plt.savefig('inventory_dashboard.png', dpi=300, bbox_inches='tight') plt.show() ``` --- ## 自动化脚本 ### Python 物控自动化工具 #### 1. 库存报表自动生成 ```python # inventory_report.py import pandas as pd import openpyxl from datetime import datetime class InventoryReporter: def __init__(self, data_file): self.data = pd.read_excel(data_file) self.report_date = datetime.now() def generate_daily_report(self): """生成日报""" report = { '日期': self.report_date.strftime('%Y-%m-%d'), '库存总金额': self.data['库存金额'].sum(), '库存物料数': len(self.data), '呆滞料金额': self.data[self.data['呆滞天数'] > 90]['库存金额'].sum(), '缺料物料数': len(self.data[self.data['库存数量'] < self.data['安全库存']]), '库存周转率': self.data['销售成本'].sum() / self.data['平均库存'].sum() } return pd.DataFrame([report]) def export_to_excel(self, output_path): """导出到 Excel""" with pd.ExcelWriter(output_path, engine='openpyxl') as writer: # 汇总表 summary = self.generate_daily_report() summary.to_excel(writer, sheet_name='汇总', index=False) # 明细表 self.data.to_excel(writer, sheet_name='库存明细', index=False) # 呆滞料表 stagnant = self.data[self.data['呆滞天数'] > 90] stagnant.to_excel(writer, sheet_name='呆滞料', index=False) # 缺料表 shortage = self.data[self.data['库存数量'] < self.data['安全库存']] shortage.to_excel(writer, sheet_name='缺料预警', index=False) print(f"报表已生成:{output_path}") ``` #### 2. 自动补货计算 ```python # auto_replenishment.py import pandas as pd import numpy as np class AutoReplenishment: def __init__(self, inventory_data, demand_data): self.inventory = inventory_data self.demand = demand_data def calculate_reorder_point(self, lead_time_days, service_level=0.95): """计算订货点""" # 计算平均日需求和标准差 avg_daily_demand = self.demand['日需求量'].mean() std_daily_demand = self.demand['日需求量'].std() # Z 值(服务水平) z_values = {0.90: 1.28, 0.95: 1.65, 0.98: 2.05, 0.99: 2.33} z = z_values.get(service_level, 1.65) # 安全库存 safety_stock = z * std_daily_demand * np.sqrt(lead_time_days) # 订货点 reorder_point = avg_daily_demand * lead_time_days + safety_stock return { '平均日需求': avg_daily_demand, '安全库存': safety_stock, '订货点': reorder_point } def generate_purchase_plan(self): """生成采购计划""" purchase_list = [] for _, item in self.inventory.iterrows(): if item['当前库存'] < item['订货点']: # 计算建议采购量 lead_time = item['采购提前期'] avg_demand = self.demand[self.demand['物料编码'] == item['物料编码']]['日需求量'].mean() # 建议采购量 = (提前期需求 + 安全库存) - 当前库存 suggested_qty = (avg_demand * lead_time + item['安全库存']) - item['当前库存'] # 考虑最小订货量(MOQ) moq = item.get('最小订货量', 1) if suggested_qty < moq: suggested_qty = moq purchase_list.append({ '物料编码': item['物料编码'], '物料名称': item['物料名称'], '当前库存': item['当前库存'], '订货点': item['订货点'], '建议采购量': suggested_qty, '供应商': item.get('供应商', ''), '预计到货日期': pd.Timestamp.now() + pd.Timedelta(days=item['采购提前期']) }) return pd.DataFrame(purchase_list) ``` #### 3. 库存预警系统 ```python # inventory_alert.py import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart import pandas as pd class InventoryAlert: def __init__(self, smtp_config): self.smtp_server = smtp_config['server'] self.smtp_port = smtp_config['port'] self.email_user = smtp_config['user'] self.email_password = smtp_config['password'] def check_inventory_status(self, inventory_df): """检查库存状态""" alerts = [] for _, item in inventory_df.iterrows(): # 缺料预警 if item['当前库存'] < item['安全库存']: alerts.append({ '类型': '缺料预警', '物料编码': item['物料编码'], '物料名称': item['物料名称'], '当前库存': item['当前库存'], '安全库存': item['安全库存'], '缺口': item['安全库存'] - item['当前库存'] }) # 呆滞料预警 if item['呆滞天数'] > 90: alerts.append({ '类型': '呆滞料预警', '物料编码': item['物料编码'], '物料名称': item['物料名称'], '呆滞天数': item['呆滞天数'], '库存金额': item['库存金额'] }) # 库存过高预警 if item['当前库存'] > item['最高库存']: alerts.append({ '类型': '库存过高', '物料编码': item['物料编码'], '物料名称': item['物料名称'], '当前库存': item['当前库存'], '最高库存': item['最高库存'] }) return pd.DataFrame(alerts) def send_alert_email(self, alerts_df, recipient): """发送预警邮件""" if alerts_df.empty: return msg = MIMEMultipart('alternative') msg['Subject'] = f'库存预警报告 - {pd.Timestamp.now().strftime("%Y-%m-%d")}' msg['From'] = self.email_user msg['To'] = recipient # 生成 HTML html = f"""

库存预警报告

生成时间:{pd.Timestamp.now().strftime("%Y-%m-%d %H:%M")}

""" for _, row in alerts_df.iterrows(): row_class = "alert-high" if row['类型'] in ['缺料预警', '呆滞料预警'] else "alert-medium" value = row.get('缺口', row.get('呆滞天数', row.get('当前库存', ''))) html += f""" """ html += """
类型 物料编码 物料名称 数值 状态
{row['类型']} {row['物料编码']} {row['物料名称']} {value} 需要处理

请及时处理预警事项!

""" msg.attach(MIMEText(html, 'html')) # 发送邮件 with smtplib.SMTP_SSL(self.smtp_server, self.smtp_port) as server: server.login(self.email_user, self.email_password) server.send_message(msg) print(f"预警邮件已发送至 {recipient}") ``` --- ## 案例研究 ### 案例 1:降低库存周转天数 **背景**: - 某电子厂库存周转天数:90 天 - 目标:降低至 60 天 **措施**: 1. ABC 分类管理 2. 优化安全库存 3. 实施 VMI(供应商管理库存) 4. 定期盘点与清理呆滞料 **结果**: - 库存周转天数降至 55 天 - 库存资金占用减少 38% - 缺料率从 5% 降至 1.5% ### 案例 2:呆滞料清理 **背景**: - 呆滞料金额:$500,000 - 占总库存:15% **措施**: 1. 呆滞料分析与分类 2. 制定清理计划(折价销售、退供应商、报废) 3. 优化采购策略 4. 建立呆滞料预警机制 **结果**: - 呆滞料减少 70% - 释放资金 $350,000 - 库存结构优化 --- ## 资源推荐 ### 书籍 1. **《物料管理实务》** - 作者:王文信 2. **《生产与运营管理》** - 作者:Richard B. Chase 3. **《供应链管理:战略、规划与运作》** - 作者:Sunil Chopra ### 在线课程 1. **Coursera** - Supply Chain Management Specialization 2. **Udemy** - Inventory Management and Control 3. **edX** - Operations Management ### 工具软件 1. **ERP 系统**:SAP、Oracle、金蝶、用友 2. **WMS 系统**:仓库管理系统 3. **Excel VBA**:自定义工具开发 ### 行业标准 1. **ISO 9001** - 质量管理体系 2. **ISO 28000** - 供应链安全管理体系 3. **APICS CPIM** - 生产与库存管理认证 --- ## 快速开始 ### 1. 安装依赖 ```bash # Python 环境 pip install pandas openpyxl matplotlib # Excel VBA # 打开 Excel → 开发工具 → Visual Basic → 导入模块 ``` ### 2. 使用示例 ```python # 导入工具库 from inventory_report import InventoryReporter from auto_replenishment import AutoReplenishment # 生成日报 reporter = InventoryReporter('inventory_data.xlsx') reporter.export_to_excel('daily_report.xlsx') # 自动补货 replenishment = AutoReplenishment(inventory_data, demand_data) purchase_plan = replenishment.generate_purchase_plan() purchase_plan.to_excel('purchase_plan.xlsx', index=False) ``` ### 3. Excel VBA 使用 ```vba ' 打开工具库 Sub Open_MC_Toolkit() Workbooks.Open "vba-mc-toolkit.xlsm" End Sub ' 运行库存预警 Sub Run_Inventory_Alert() Call Inventory_Alert End Sub ' 生成盘点表 Sub Run_Generate_Count_Sheet() Call Generate_Inventory_Count_Sheet End Sub ``` --- ## 贡献指南 欢迎贡献你的物控经验和工具! ### 如何贡献 1. Fork 本仓库 2. 创建你的分支 (`git checkout -b feature/your-feature`) 3. 提交你的更改 (`git commit -m 'Add some feature'`) 4. 推送到分支 (`git push origin feature/your-feature`) 5. 创建 Pull Request ### 贡献内容 - ✅ Excel VBA 工具脚本 - ✅ Python 自动化工具 - ✅ 物控案例分析 - ✅ 最佳实践文档 - ✅ 数据分析模板 --- ## 许可证 本项目采用 MIT 许可证 - 详见 [LICENSE](LICENSE) 文件 --- ## 联系方式 如有问题或建议,请通过以下方式联系: - GitHub Issues: [提交 Issue](https://github.com/1803560007/物控学习笔记/issues) - 邮箱: 1803560007@github.com --- ## 更新日志 ### v1.0.0 (2026-02-03) - ✅ 创建物控学习笔记仓库 - ✅ 添加基础知识文档 - ✅ 添加 Excel VBA 工具库 - ✅ 添加 Python 自动化脚本 - ✅ 添加案例研究 - ✅ 添加资源推荐 --- **最后更新**: 2026-02-03 **维护者**: 1803560007 **版本**: v1.0.0