- Add new mBOMRepository.bas module for data access layer with LoadAll/SaveAll/InsertNewBOMRow functions - Refactor cBOMRow.cls property methods for better readability and formatting - Add comprehensive unit tests for BOM repository functionality in mTestEngine Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
127 lines
5.2 KiB
QBasic
127 lines
5.2 KiB
QBasic
' ==============================================================================
|
||
' 模块名称: mBOMRepository
|
||
' 模块类别: 标准模块 (Standard Module)
|
||
' 所属项目: BOMForge
|
||
' 模块职责: 负责 Excel 表格与 cBOMRow 内存对象之间的双向数据交互
|
||
' ==============================================================================
|
||
Option Explicit
|
||
|
||
' ------------------------------------------------------------------------------
|
||
' 函数名称: LoadAllBOMs
|
||
' 函数功能: 将工作表中的 BOM 数据逐行加载为 cBOMRow 对象的集合
|
||
' 参数说明: ws - 目标工作表对象
|
||
' ------------------------------------------------------------------------------
|
||
Public Function LoadAllBOMs(ws As Worksheet) As Collection
|
||
Dim coll As New Collection
|
||
Dim lastRow As Long
|
||
Dim i As Long
|
||
Dim rowObj As cBOMRow
|
||
|
||
' 获取 A 列最后一行 (假设 A 列总是有数据的,如行号)
|
||
lastRow = ws.Cells(ws.Rows.count, "A").End(xlUp).row
|
||
|
||
' 根据业务说明,表头在第3行,数据从第4行开始
|
||
If lastRow < 4 Then
|
||
Set LoadAllBOMs = coll
|
||
Exit Function
|
||
End If
|
||
|
||
For i = 4 To lastRow
|
||
Set rowObj = New cBOMRow
|
||
|
||
' 映射 Excel 列到对象属性
|
||
rowObj.ExcelRowIndex = i
|
||
rowObj.RowNo = Val(ws.Cells(i, 1).value)
|
||
rowObj.ModuleType = Trim(ws.Cells(i, 2).value)
|
||
rowObj.Code = Trim(ws.Cells(i, 3).value)
|
||
rowObj.ItemName = Trim(ws.Cells(i, 4).value)
|
||
rowObj.Quantity = Val(ws.Cells(i, 5).value)
|
||
rowObj.Condition = Trim(ws.Cells(i, 6).value)
|
||
rowObj.Remark = Trim(ws.Cells(i, 7).value)
|
||
rowObj.Category = Trim(ws.Cells(i, 8).value)
|
||
rowObj.ParentCategory = Trim(ws.Cells(i, 9).value)
|
||
rowObj.CategoryCondition = Trim(ws.Cells(i, 10).value)
|
||
rowObj.Code66 = Trim(ws.Cells(i, 11).value)
|
||
rowObj.BIPBaseRowNo = Trim(ws.Cells(i, 12).value)
|
||
|
||
' 【关键】刚从 Excel 读取的数据是原生态的,重置脏标记
|
||
rowObj.ResetDirtyFlag
|
||
|
||
coll.Add rowObj
|
||
Next i
|
||
|
||
Set LoadAllBOMs = coll
|
||
End Function
|
||
|
||
' ------------------------------------------------------------------------------
|
||
' 函数名称: SaveAll
|
||
' 函数功能: 遍历集合,仅将发生改变 (IsDirty = True) 的对象写回 Excel
|
||
' 参数说明: ws - 目标工作表对象, bomCollection - 内存对象集合
|
||
' ------------------------------------------------------------------------------
|
||
Public Sub SaveAll(ws As Worksheet, bomCollection As Collection)
|
||
Dim rowObj As cBOMRow
|
||
Dim r As Long
|
||
|
||
For Each rowObj In bomCollection
|
||
' 【性能核心】只写回被业务策略修改过的行
|
||
If rowObj.IsDirty Then
|
||
r = rowObj.ExcelRowIndex
|
||
|
||
' 如果是新增行,ExcelRowIndex 可能为空或需要重新计算
|
||
If r <= 0 Then
|
||
r = ws.Cells(ws.Rows.count, "A").End(xlUp).row + 1
|
||
rowObj.ExcelRowIndex = r
|
||
End If
|
||
|
||
' 将属性写回对应的列
|
||
ws.Cells(r, 1).value = rowObj.RowNo
|
||
ws.Cells(r, 2).value = rowObj.ModuleType
|
||
ws.Cells(r, 3).value = rowObj.Code
|
||
ws.Cells(r, 4).value = rowObj.ItemName
|
||
ws.Cells(r, 5).value = rowObj.Quantity
|
||
ws.Cells(r, 6).value = rowObj.Condition
|
||
ws.Cells(r, 7).value = rowObj.Remark
|
||
ws.Cells(r, 8).value = rowObj.Category
|
||
ws.Cells(r, 9).value = rowObj.ParentCategory
|
||
ws.Cells(r, 10).value = rowObj.CategoryCondition
|
||
ws.Cells(r, 11).value = rowObj.Code66
|
||
ws.Cells(r, 12).value = rowObj.BIPBaseRowNo
|
||
|
||
' 保存完毕,重置脏标记
|
||
rowObj.ResetDirtyFlag
|
||
End If
|
||
Next rowObj
|
||
End Sub
|
||
|
||
' ------------------------------------------------------------------------------
|
||
' 函数名称: InsertNewBOMRow
|
||
' 函数功能: 基于现有行克隆出一个新行对象,用于弹性元件等需要全新规格新增的场景
|
||
' ------------------------------------------------------------------------------
|
||
Public Function InsertNewBOMRow(bomCollection As Collection, copyFromObj As cBOMRow) As cBOMRow
|
||
Dim newObj As New cBOMRow
|
||
|
||
' 设置为 0 意味着在 SaveAll 时,它会自动追加到 Excel 的最后一行
|
||
newObj.ExcelRowIndex = 0
|
||
|
||
' 属性克隆
|
||
newObj.RowNo = copyFromObj.RowNo ' 这里的行号往往需要外部策略重新编排,先克隆
|
||
newObj.ModuleType = copyFromObj.ModuleType
|
||
newObj.Code = copyFromObj.Code ' 同样等待外部策略分配新代码
|
||
newObj.ItemName = copyFromObj.ItemName
|
||
newObj.Quantity = copyFromObj.Quantity
|
||
newObj.Condition = copyFromObj.Condition
|
||
newObj.Remark = copyFromObj.Remark
|
||
newObj.Category = copyFromObj.Category
|
||
newObj.ParentCategory = copyFromObj.ParentCategory
|
||
newObj.CategoryCondition = copyFromObj.CategoryCondition
|
||
newObj.Code66 = copyFromObj.Code66
|
||
newObj.BIPBaseRowNo = copyFromObj.BIPBaseRowNo
|
||
|
||
' 强制触发一下脏标记,确保这个新对象会被 SaveAll 捕获写进 Excel
|
||
' 由于 Let 属性判断 <> 才会触发,我们采用一个小技巧
|
||
newObj.Code = newObj.Code & "_TEMP"
|
||
newObj.Code = copyFromObj.Code
|
||
|
||
bomCollection.Add newObj
|
||
Set InsertNewBOMRow = newObj
|
||
End Function |