feat: add BIP upload module for order processing

Add BIPUploadModule to process product orders and generate BIP upload format:
- Read order data from [产品订单] worksheet
- Extract BOM using existing BomExtractor and ProductModelParser
- Output to [BIP上传模板] with formatted fields:
  - Source document number, product code, quantity
  - Line number (base 7000 + index)
  - Material code (66 code from BOM)
  - Supply method, required date, issue organization
  - Planned outbound quantity, remarks for errors

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Misaka
2026-02-01 22:07:36 +08:00
parent 79dc7cbf72
commit 8fae8f0389
2 changed files with 400 additions and 0 deletions

View File

@@ -0,0 +1,394 @@
'=====================================================================
' 模块名: BIPUploadModule
' 功能: 处理产品订单数据提取BOM后生成[BIP上传模板]格式数据
' 作者: Auto-generated
' 日期: 2026-02-01
'=====================================================================
Option Explicit
'=====================================================================
' 常量定义
'=====================================================================
' 提取条件配置
Private Const CONDITION_CONFIG = "azxs,安装形式|bkxs,表壳形式|gclj,过程连接|jycz,接液材质|lcfw,量程范围"
' 行号基数
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 outputRow As Long
outputRow = 2 ' 从第2行开始输出第1行是表头
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
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列产品编码
' 跳过空行
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
' 处理单个订单
outputRow = ProcessSingleOrder(orderNumber, productModel, quantity, productCode, _
BomExtractor, bipSheet, outputRow)
processedCount = processedCount + 1
ContinueLoop:
Next i
' 格式化BIP上传模板
FormatBIPSheet bipSheet
Dim elapsedTime As Double
elapsedTime = Timer - startTime
MsgBox "处理完成!" & vbCrLf & _
"处理订单数: " & orderCount & vbCrLf & _
"生成BIP行数: " & (outputRow - 2) & vbCrLf & _
"用时: " & Format(elapsedTime, "0.00") & "秒", vbInformation
' 激活BIP上传模板
bipSheet.Activate
Exit Sub
ErrorHandler:
MsgBox "处理异常: " & Err.description, vbCritical
End Sub
'=====================================================================
' 函数: ProcessSingleOrder
' 功能: 处理单个订单提取BOM并写入BIP上传模板
' 参数: orderNumber - 生产订单号
' productModel - 产品型号
' quantity - 生产数量
' productCode - 产品编码
' BomExtractor - BOM提取器对象
' bipSheet - BIP上传模板工作表
' startRow - 起始行号
' 返回: Long - 下一个可用行号
'=====================================================================
Private Function ProcessSingleOrder(orderNumber As String, _
productModel As String, _
quantity As String, _
productCode As String, _
BomExtractor As BomExtractor, _
bipSheet As Worksheet, _
startRow As Long) As Long
On Error Resume Next
Dim currentRow As Long
currentRow = startRow
' 解析产品型号
Dim parser As ProductModelParser
Set parser = New ProductModelParser
Dim extractNote As String
extractNote = ""
If Not parser.Parse(productModel) Then
' 解析失败,写入一行错误记录
extractNote = "解析失败: " & parser.ErrorMessage
WriteBIPRow bipSheet, currentRow, orderNumber, productCode, quantity, _
1, "", extractNote
ProcessSingleOrder = currentRow + 1
Exit Function
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
WriteBIPRow bipSheet, currentRow, orderNumber, productCode, quantity, _
1, "", extractNote
currentRow = currentRow + 1
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行
WriteBIPRow bipSheet, currentRow, orderNumber, productCode, quantity, _
lineIndex, item.Code66, itemNote
currentRow = currentRow + 1
lineIndex = lineIndex + 1
Next item
End If
ProcessSingleOrder = currentRow
End Function
'=====================================================================
' 过程: 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
'=====================================================================
' 过程: WriteBIPRow
' 功能: 写入BIP上传模板数据行
' 参数: ws - 工作表对象
' row - 行号
' orderNumber - 生产订单号
' productCode - 产品编码
' quantity - 生产数量
' lineIndex - 行号索引从1开始
' materialCode - 材料编码66编码
' note - 备注
'=====================================================================
Private Sub WriteBIPRow(ws As Worksheet, _
row As Long, _
orderNumber As String, _
productCode As String, _
quantity As String, _
lineIndex As Long, _
materialCode As String, _
note As String)
' 列1来源单据号生产订单号
ws.Cells(row, 1).value = orderNumber
' 列2产品编码
ws.Cells(row, 2).value = productCode
' 列3生产数量
ws.Cells(row, 3).value = quantity
' 列4行号 = 基数 + 索引
ws.Cells(row, 4).value = ROW_NUMBER_BASE + lineIndex
' 列5材料编码66编码
ws.Cells(row, 5).value = materialCode
' 列6供应方式固定值
ws.Cells(row, 6).value = "一般发料"
' 列7需用日期当天日期
ws.Cells(row, 7).value = Date
' 列8发料组织固定值
ws.Cells(row, 8).value = "重庆布莱迪仪器仪表有限公司"
' 列9计划出库数量与生产数量一致
ws.Cells(row, 9).value = quantity
' 列10备注
ws.Cells(row, 10).value = note
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