'===================================================================== ' 模块名: BIPUploadModule ' 功能: 处理产品订单数据,提取BOM后生成[BIP上传模板]格式数据 '===================================================================== Option Explicit '===================================================================== ' 常量定义 '===================================================================== ' 提取条件配置 Private Const CONDITION_CONFIG = "azxs,安装形式|bkxs,表壳形式|gclj,过程连接|jycz,接液材质|lcfw,量程范围|fjgn,附加功能" ' 行号基数 Private Const ROW_NUMBER_BASE = 7000 '===================================================================== ' 过程: ProcessOrdersToBIP ' 功能: 处理产品订单数据,生成BIP上传格式 ' 说明: 主入口程序,从[产品订单]读取数据,输出到[BIP上传模板] '===================================================================== Public Sub ProcessOrdersToBIP() On Error GoTo ErrorHandler Dim startTime As Double startTime = Timer ' 准备工作表对象 Dim orderSheet As Worksheet Dim bipSheet As Worksheet Dim bomSheet As Worksheet ' 获取[产品订单]工作表 Set orderSheet = GetOrderSheet() If orderSheet Is Nothing Then MsgBox "未找到[产品订单]工作表!", vbCritical Exit Sub End If ' 获取[BIP上传模板]工作表 Set bipSheet = GetBIPUploadSheet() ' 获取BOM库工作表 Set bomSheet = GetBomSheet() If bomSheet Is Nothing Then MsgBox "未找到[平台配置清单]工作表!", vbCritical Exit Sub End If ' 初始化BOM提取器 Dim BomExtractor As BomExtractor Set BomExtractor = New BomExtractor BomExtractor.SetWorksheet bomSheet If Not BomExtractor.LoadBomData Then MsgBox "加载BOM数据失败:" & BomExtractor.GetErrorSummary, vbCritical Exit Sub End If ' 清空BIP上传模板数据(保留表头) ClearBIPSheetData bipSheet ' 写入BIP上传模板表头 WriteBIPHeader bipSheet ' 获取订单数据行数 Dim lastRow As Long lastRow = orderSheet.Cells(orderSheet.Rows.Count, 1).End(xlUp).row ' 如果只有表头或没有数据 If lastRow < 2 Then MsgBox "[产品订单]工作表中没有数据!", vbExclamation Exit Sub End If ' 处理每个订单,收集所有输出数据 Dim outputData As collection Set outputData = New collection Dim i As Long Dim processedCount As Long Dim orderCount As Long processedCount = 0 orderCount = 0 For i = 2 To lastRow ' 读取订单数据 Dim orderNumber As String Dim productModel As String Dim quantity As String Dim productCode As String Dim componentPriority As String orderNumber = Trim(orderSheet.Cells(i, 1).value) ' A列:生产订单号 productModel = Trim(orderSheet.Cells(i, 2).value) ' B列:产品型号 quantity = Trim(orderSheet.Cells(i, 3).value) ' C列:数量 productCode = Trim(orderSheet.Cells(i, 4).value) ' D列:产品编码 componentPriority = Trim(orderSheet.Cells(i, 5).value) ' E列:部件优先 ' 跳过空行 If orderNumber = "" And productModel = "" Then GoTo ContinueLoop End If ' 验证必填字段 If orderNumber = "" Then MsgBox "第" & i & "行:生产订单号为空,跳过该行!", vbExclamation GoTo ContinueLoop End If If productModel = "" Then MsgBox "第" & i & "行:产品型号为空,跳过该行!", vbExclamation GoTo ContinueLoop End If If quantity = "" Then MsgBox "第" & i & "行:数量为空,跳过该行!", vbExclamation GoTo ContinueLoop End If orderCount = orderCount + 1 ' 处理单个订单,收集输出数据 ProcessSingleOrder orderNumber, productModel, quantity, productCode, _ componentPriority, BomExtractor, outputData processedCount = processedCount + 1 ContinueLoop: Next i ' 批量写入数据到工作表 If outputData.Count > 0 Then WriteBatchData bipSheet, outputData End If ' 格式化BIP上传模板 FormatBIPSheet bipSheet Dim elapsedTime As Double elapsedTime = Timer - startTime MsgBox "处理完成!" & vbCrLf & _ "处理订单数: " & orderCount & vbCrLf & _ "生成BIP行数: " & outputData.Count & vbCrLf & _ "用时: " & Format(elapsedTime, "0.00") & "秒", vbInformation ' 激活BIP上传模板 bipSheet.Activate Exit Sub ErrorHandler: MsgBox "处理异常: " & Err.description, vbCritical End Sub '===================================================================== ' 过程: ProcessSingleOrder ' 功能: 处理单个订单,提取BOM并将数据添加到输出集合 ' 参数: orderNumber - 生产订单号 ' productModel - 产品型号 ' quantity - 生产数量 ' productCode - 产品编码 ' componentPriority - 部件优先标志("是"或"否") ' BomExtractor - BOM提取器对象 ' outputData - 输出数据集合 '===================================================================== Private Sub ProcessSingleOrder(orderNumber As String, _ productModel As String, _ quantity As String, _ productCode As String, _ componentPriority As String, _ BomExtractor As BomExtractor, _ outputData As collection) On Error Resume Next ' 根据部件优先设置排除类别 BomExtractor.ClearExcludeCategories If UCase(componentPriority) = "否" Or componentPriority = "0" Or componentPriority = "FALSE" Then Dim excludeCats As New collection excludeCats.Add "部件" BomExtractor.SetExcludeCategories excludeCats End If ' 解析产品型号 Dim parser As ProductModelParser Set parser = New ProductModelParser Dim extractNote As String extractNote = "" If Not parser.Parse(productModel) Then ' 解析失败,添加一行错误记录 extractNote = "解析失败: " & parser.ErrorMessage outputData.Add CreateBIPRowArray(orderNumber, productCode, quantity, 1, "", extractNote) Exit Sub End If ' 提取BOM Dim matchedItems As collection Set matchedItems = BomExtractor.ExtractBom(parser.Conditions) ' 获取错误信息 Dim bomErrors As String bomErrors = BomExtractor.GetErrorSummary If bomErrors <> "" Then extractNote = bomErrors End If ' 输出结果 If matchedItems.Count = 0 Then ' 没有匹配项,添加一行空记录 If extractNote = "" Then extractNote = "未匹配到任何物料" End If outputData.Add CreateBIPRowArray(orderNumber, productCode, quantity, 1, "", extractNote) Else ' 输出每个匹配的物料 Dim item As BomItem Dim lineIndex As Long lineIndex = 1 For Each item In matchedItems Dim itemNote As String itemNote = extractNote ' 添加物料特定的错误 If item.MatchError <> "" Then If itemNote <> "" Then itemNote = itemNote & "; " itemNote = itemNote & item.MatchError End If ' 创建BIP行数据并添加到集合 outputData.Add CreateBIPRowArray(orderNumber, productCode, quantity, _ lineIndex, item.Code66, itemNote) lineIndex = lineIndex + 1 Next item End If End Sub '===================================================================== ' 函数: CreateBIPRowArray ' 功能: 创建BIP上传模板一行数据的数组 ' 参数: orderNumber - 生产订单号 ' productCode - 产品编码 ' quantity - 生产数量 ' lineIndex - 行号索引(从1开始) ' materialCode - 材料编码(66编码) ' note - 备注 ' 返回: Variant() - 包含10个元素的数组 '===================================================================== Private Function CreateBIPRowArray(orderNumber As String, _ productCode As String, _ quantity As String, _ lineIndex As Long, _ materialCode As String, _ note As String) As Variant() Dim rowData(1 To 10) As Variant rowData(1) = orderNumber ' 来源单据号(生产订单号) rowData(2) = productCode ' 产品编码 rowData(3) = quantity ' 生产数量 rowData(4) = ROW_NUMBER_BASE + lineIndex ' 行号 = 基数 + 索引 rowData(5) = materialCode ' 材料编码(66编码) rowData(6) = "一般发料" ' 供应方式(固定值) rowData(7) = Date ' 需用日期(当天日期) rowData(8) = "重庆布莱迪仪器仪表有限公司" ' 发料组织(固定值) rowData(9) = quantity ' 计划出库数量(与生产数量一致) rowData(10) = note ' 备注 CreateBIPRowArray = rowData End Function '===================================================================== ' 过程: WriteBatchData ' 功能: 批量写入数据到工作表 ' 参数: ws - 工作表对象 ' outputData - 输出数据集合,每个元素是一个一维数组 '===================================================================== Private Sub WriteBatchData(ws As Worksheet, outputData As collection) ' 如果没有数据,直接返回 If outputData.Count = 0 Then Exit Sub End If ' 创建二维数组 Dim rowCount As Long rowCount = outputData.Count Dim resultData() As Variant ReDim resultData(1 To rowCount, 1 To 10) ' 填充数据到二维数组 Dim i As Long Dim rowArray As Variant For i = 1 To rowCount rowArray = outputData(i) resultData(i, 1) = rowArray(1) resultData(i, 2) = rowArray(2) resultData(i, 3) = rowArray(3) resultData(i, 4) = rowArray(4) resultData(i, 5) = rowArray(5) resultData(i, 6) = rowArray(6) resultData(i, 7) = rowArray(7) resultData(i, 8) = rowArray(8) resultData(i, 9) = rowArray(9) resultData(i, 10) = rowArray(10) Next i ' 一次性写入工作表(从第2行开始) ws.Range("A2").Resize(rowCount, 10).value = resultData End Sub '===================================================================== ' 过程: WriteBIPHeader ' 功能: 写入BIP上传模板表头 ' 参数: ws - 工作表对象 '===================================================================== Private Sub WriteBIPHeader(ws As Worksheet) ' 第1行:主表头 ws.Cells(1, 1).value = "来源单据号(生产订单号)" ws.Cells(1, 2).value = "产品编码" ws.Cells(1, 3).value = "生产数量" ws.Cells(1, 4).value = "行号" ws.Cells(1, 5).value = "材料编码" ws.Cells(1, 6).value = "供应方式" ws.Cells(1, 7).value = "需用日期" ws.Cells(1, 8).value = "发料组织" ws.Cells(1, 9).value = "计划出库数量" ws.Cells(1, 10).value = "备注" End Sub '===================================================================== ' 函数: GetOrderSheet ' 功能: 获取[产品订单]工作表 ' 返回: Worksheet - 工作表对象 '===================================================================== Private Function GetOrderSheet() As Worksheet On Error Resume Next Set GetOrderSheet = ThisWorkbook.Worksheets("产品订单") On Error GoTo 0 End Function '===================================================================== ' 函数: GetBIPUploadSheet ' 功能: 获取或创建[BIP上传模板]工作表 ' 返回: Worksheet - 工作表对象 '===================================================================== Private Function GetBIPUploadSheet() As Worksheet Dim wsName As String wsName = "BIP上传模板" On Error Resume Next Set GetBIPUploadSheet = ThisWorkbook.Worksheets(wsName) On Error GoTo 0 If GetBIPUploadSheet Is Nothing Then ' 创建新工作表 Set GetBIPUploadSheet = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count)) GetBIPUploadSheet.Name = wsName End If End Function '===================================================================== ' 函数: GetBomSheet ' 功能: 获取BOM工作表 ' 返回: Worksheet - BOM工作表对象 '===================================================================== Private Function GetBomSheet() As Worksheet On Error Resume Next Set GetBomSheet = ThisWorkbook.Worksheets("平台配置清单") On Error GoTo 0 End Function '===================================================================== ' 过程: ClearBIPSheetData ' 功能: 清空BIP上传模板的数据(保留表头) ' 参数: ws - 工作表对象 '===================================================================== Private Sub ClearBIPSheetData(ws As Worksheet) ' 清空从第2行开始的所有数据 Dim lastRow As Long lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).row If lastRow > 1 Then ws.Rows("2:" & lastRow).ClearContents End If End Sub '===================================================================== ' 过程: FormatBIPSheet ' 功能: 格式化BIP上传模板工作表 ' 参数: ws - 工作表对象 '===================================================================== Private Sub FormatBIPSheet(ws As Worksheet) On Error Resume Next ' 设置表头格式 With ws.Rows(1) .Font.Bold = True .Interior.Color = RGB(217, 217, 217) .HorizontalAlignment = xlCenter End With ' 设置所有单元格居中对齐 With ws.UsedRange .HorizontalAlignment = xlCenter .VerticalAlignment = xlCenter End With ' 自动调整列宽 ws.Columns.AutoFit ' 设置日期列格式 ws.Columns(7).NumberFormat = "yyyy/mm/dd" On Error GoTo 0 End Sub