当前位置:首页 » 创享学习 » 用对AI,效率快的不得了!!!产品清单比较宏代码

分类页和文章页“当前位置”下方广告(PC版),后台可以自由更改

用对AI,效率快的不得了!!!产品清单比较宏代码

31°c 2026年02月06日 23:03 创享学习 0条评论
  移步手机端

1、打开你手机的二维码扫描APP
2、扫描左则的二维码
3、点击扫描获得的网址
4、可以在手机端阅读此文章
用对AI,效率快的不得了!!!产品清单比较宏代码摘要:

两份排序杂乱无章的产品清单,使用下面的宏代码,16秒搞定!功能特点:...

总字数:75677

两份排序杂乱无章的产品清单,使用下面的宏代码,16秒搞定!

功能特点:

完整功能:支持.xls/.xlsx/.xlsm/.xlsb全格式对比
智能对比:以编码为主键,双向查找对比
差异标记:红色/绿色标注不同数据,橙色标注独有编码
注释系统:详细说明差异位置和类型
层次处理:自动识别BOM层级关系
性能优化:字典索引快速查找,跳过空行
结果统计:完整对比报告和用时统计
制造业、供应链管理或物料清单管理需要频繁对比BOM文件,能大幅提高工作效率。


使用方法:
Excel先开启宏,文件/选项/信任中心/~设置-宏设置-选择:启用所有宏

打开第一个文件,按Alt+F11打开宏编辑界面,插入-模块,复制宏代码,

再回到第一个文件,按Alt+F8,点执行,打开第二个文件即可对比完成。

BOM.jpg

Option Explicit

' ============================================================
' 主程序:BOM文件智能对比(优化列位置版)
' ============================================================
Sub CompareBOMFilesIntelligent()
    Dim wbA As Workbook, wbB As Workbook
    Dim wsA As Worksheet, wsB As Worksheet
    Dim lastRowA As Long, lastRowB As Long
    Dim startTime As Double, totalTime As Double, indexTime As Double
    Dim i As Long, j As Long, foundRow As Long
    Dim diffDetails As String, matchMethod As String
    
    ' 记录开始时间
    startTime = Timer
    On Error GoTo ErrorHandler
    
    ' 设置主工作簿
    Set wbA = ThisWorkbook
    Set wsA = wbA.Sheets(1)
    
    ' 选择B文件
    Dim filePathB As String
    filePathB = Application.GetOpenFilename("Excel文件 (*.xls;*.xlsx;*.xlsm;*.xlsb),*.xls;*.xlsx;*.xlsm;*.xlsb", , "请选择B文件")
    If filePathB = "False" Then Exit Sub
    
    ' 打开B文件
    Dim fileExt As String
    fileExt = LCase(Right(filePathB, 4))
    
    If fileExt = ".xls" Then
        Set wbB = Workbooks.Open(filePathB, UpdateLinks:=False, ReadOnly:=True)
    Else
        Set wbB = Workbooks.Open(filePathB, UpdateLinks:=False, ReadOnly:=True)
    End If
    
    ' 获取工作表
    On Error Resume Next
    Set wsB = wbB.Sheets(1)
    If wsB Is Nothing Then
        MsgBox "无法访问B文件的第一个工作表。", vbExclamation
        Exit Sub
    End If
    On Error GoTo ErrorHandler
    
    ' 获取数据范围
    lastRowA = GetLastRow(wsA, 2)
    lastRowB = GetLastRow(wsB, 2)
    
    ' 检查数据
    If lastRowA <= 1 Or lastRowB <= 1 Then
        MsgBox "文件没有有效数据。", vbExclamation
        GoTo Cleanup
    End If
    
    ' 优化性能设置
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False
    Application.DisplayAlerts = False
    
    ' 清除格式
    ClearAllFormats wsA, lastRowA
    ClearAllFormats wsB, lastRowB
    
    ' 添加对比结果列(从J列开始,避开I列)
    Dim commentColA As Long, commentColB As Long
    commentColA = GetLastColumn(wsA) + 2  ' 增加1列,从J列开始
    commentColB = GetLastColumn(wsB) + 2
    
    ' 确保列位置正确
    If commentColA < 10 Then commentColA = 10  ' 确保从J列(第10列)开始
    If commentColB < 10 Then commentColB = 10
    
    ' 设置标题
    SetupCommentHeaders wsA, commentColA, "A"
    SetupCommentHeaders wsB, commentColB, "B"
    
    ' 添加版本差异列(从K列开始)
    Dim versionColA As Long, versionColB As Long
    versionColA = commentColA + 1
    versionColB = commentColB + 1
    SetupVersionHeaders wsA, versionColA, "A"
    SetupVersionHeaders wsB, versionColB, "B"
    
    ' ========== 阶段1:建立B文件多层智能索引 ==========
    indexTime = Timer
    
    ' 创建多层索引字典
    Dim dictFullCode As Object      ' 完整编码索引
    Dim dictFirst9Code As Object    ' 前9位编码索引
    Dim dictCodeC As Object         ' 编码+C列索引
    Dim dictFirst9CodeC As Object   ' 前9位编码+C列索引
    Dim dictCDI As Object           ' C列+D列+I列索引
    Dim dictCI As Object            ' C列+I列索引
    Dim dictC As Object             ' C列索引
    
    Set dictFullCode = CreateObject("Scripting.Dictionary")
    Set dictFirst9Code = CreateObject("Scripting.Dictionary")
    Set dictCodeC = CreateObject("Scripting.Dictionary")
    Set dictFirst9CodeC = CreateObject("Scripting.Dictionary")
    Set dictCDI = CreateObject("Scripting.Dictionary")
    Set dictCI = CreateObject("Scripting.Dictionary")
    Set dictC = CreateObject("Scripting.Dictionary")
    
    ' 索引统计
    Dim indexStats(1 To 7) As Long
    For i = 1 To 7
        indexStats(i) = 0
    Next i
    
    ' 批量读取B文件数据到数组(B列到I列,I列是第9列)
    Dim bData() As Variant
    Dim bRange As Range
    Set bRange = wsB.Range("B2:I" & lastRowB)
    bData = bRange.Value
    
    ' 建立多层索引
    For i = 1 To UBound(bData, 1)
        Dim codeB As String, cValueB As String, dValueB As String, iValueB As String
        Dim first9CodeB As String
        
        ' 获取数据(使用Trim去除首尾空格)
        codeB = TrimText(bData(i, 1))   ' B列
        cValueB = TrimText(bData(i, 2))  ' C列
        dValueB = TrimText(bData(i, 3))  ' D列
        iValueB = TrimText(bData(i, 8))  ' I列(第8列对应数组索引8)
        
        ' 解析12位物料编码
        If Len(codeB) >= 9 Then
            first9CodeB = Left(codeB, 9)
        End If
        
        ' 1. 完整编码索引
        If codeB <> "" And Len(codeB) = 12 Then
            If Not dictFullCode.Exists(codeB) Then
                dictFullCode.Add codeB, i
                indexStats(1) = indexStats(1) + 1
            End If
        End If
        
        ' 2. 前9位编码索引
        If first9CodeB <> "" And Len(first9CodeB) = 9 Then
            If Not dictFirst9Code.Exists(first9CodeB) Then
                dictFirst9Code.Add first9CodeB, i
                indexStats(2) = indexStats(2) + 1
            End If
        End If
        
        ' 3. 编码+C列索引
        If codeB <> "" And cValueB <> "" Then
            Dim keyCodeC As String
            keyCodeC = codeB & "||" & cValueB
            If Not dictCodeC.Exists(keyCodeC) Then
                dictCodeC.Add keyCodeC, i
                indexStats(3) = indexStats(3) + 1
            End If
        End If
        
        ' 4. 前9位编码+C列索引
        If first9CodeB <> "" And cValueB <> "" Then
            Dim keyFirst9CodeC As String
            keyFirst9CodeC = first9CodeB & "||" & cValueB
            If Not dictFirst9CodeC.Exists(keyFirst9CodeC) Then
                dictFirst9CodeC.Add keyFirst9CodeC, i
                indexStats(4) = indexStats(4) + 1
            End If
        End If
        
        ' 5. C列+D列+I列组合索引
        If cValueB <> "" And dValueB <> "" And iValueB <> "" Then
            Dim keyCDI As String
            keyCDI = cValueB & "||" & dValueB & "||" & iValueB
            If Not dictCDI.Exists(keyCDI) Then
                dictCDI.Add keyCDI, i
                indexStats(5) = indexStats(5) + 1
            End If
        End If
        
        ' 6. C列+I列索引
        If cValueB <> "" And iValueB <> "" Then
            Dim keyCI As String
            keyCI = cValueB & "||" & iValueB
            If Not dictCI.Exists(keyCI) Then
                dictCI.Add keyCI, i
                indexStats(6) = indexStats(6) + 1
            End If
        End If
        
        ' 7. C列索引
        If cValueB <> "" Then
            If Not dictC.Exists(cValueB) Then
                dictC.Add cValueB, i
                indexStats(7) = indexStats(7) + 1
            End If
        End If
    Next i
    
    indexTime = Timer - indexTime
    
    ' ========== 阶段2:批量读取A文件数据 ==========
    Dim aData() As Variant
    Dim aRange As Range
    Set aRange = wsA.Range("B2:I" & lastRowA)
    aData = aRange.Value
    
    ' ========== 阶段3:智能匹配对比 ==========
    Dim matchStats As Object
    Set matchStats = CreateObject("Scripting.Dictionary")
    matchStats.Add "跳过", 0
    matchStats.Add "完全编码匹配", 0
    matchStats.Add "物料版本不同", 0
    matchStats.Add "编码+C列匹配", 0
    matchStats.Add "前9位编码+C列匹配", 0
    matchStats.Add "CDI匹配", 0
    matchStats.Add "CI匹配", 0
    matchStats.Add "C列匹配", 0
    matchStats.Add "未匹配", 0
    
    Dim diffCount As Long, versionDiffCount As Long
    diffCount = 0
    versionDiffCount = 0
    
    ' 记录已匹配的B文件行
    Dim matchedRowsB As Object
    Set matchedRowsB = CreateObject("Scripting.Dictionary")
    
    ' 记录版本差异
    Dim versionDiffs As Object
    Set versionDiffs = CreateObject("Scripting.Dictionary")
    
    ' 智能匹配主循环
    For i = 1 To UBound(aData, 1)
        Dim codeA As String, cValueA As String, dValueA As String, gValueA As String, iValueA As String
        Dim first9CodeA As String, last3CodeA As String
        
        ' 获取A文件数据(使用Trim去除首尾空格)
        codeA = TrimText(aData(i, 1))   ' B列
        cValueA = TrimText(aData(i, 2))  ' C列
        dValueA = TrimText(aData(i, 3))  ' D列
        gValueA = TrimText(aData(i, 6))  ' G列
        iValueA = TrimText(aData(i, 8))  ' I列
        
        ' 解析A文件编码
        If Len(codeA) >= 9 Then
            first9CodeA = Left(codeA, 9)
            If Len(codeA) = 12 Then
                last3CodeA = Mid(codeA, 10, 3)
            End If
        End If
        
        ' 检查是否为完全空行(不标注)
        If IsCompletelyEmptyRow(codeA, cValueA, dValueA, gValueA, iValueA) Then
            matchStats("跳过") = matchStats("跳过") + 1
            GoTo ContinueLoopA
        End If
        
        ' 检查是否需要对比
        If Not HasContentToCompare(codeA, cValueA, dValueA, iValueA) Then
            matchStats("跳过") = matchStats("跳过") + 1
            GoTo ContinueLoopA
        End If
        
        ' 智能匹配查找
        foundRow = 0
        matchMethod = ""
        
        ' 优先级1:完整12位编码匹配
        If codeA <> "" And Len(codeA) = 12 Then
            If dictFullCode.Exists(codeA) Then
                foundRow = dictFullCode(codeA)
                matchMethod = "完全编码匹配"
                matchStats("完全编码匹配") = matchStats("完全编码匹配") + 1
            End If
        End If
        
        ' 优先级2:前9位编码匹配
        If foundRow = 0 And first9CodeA <> "" Then
            If dictFirst9Code.Exists(first9CodeA) Then
                foundRow = dictFirst9Code(first9CodeA)
                Dim matchedCodeB As String
                matchedCodeB = TrimText(bData(foundRow, 1))
                
                ' 检查是否是完全匹配
                If codeA = matchedCodeB Then
                    ' 完全相同的编码
                    matchMethod = "完全匹配"
                    matchStats("完全编码匹配") = matchStats("完全编码匹配") + 1
                ElseIf Len(matchedCodeB) = 12 Then
                    ' 前9位相同,后3位不同
                    Dim matchedLast3CodeB As String
                    matchedLast3CodeB = Mid(matchedCodeB, 10, 3)
                    matchMethod = "物料版本不同"
                    matchStats("物料版本不同") = matchStats("物料版本不同") + 1
                    
                    ' 记录版本差异
                    versionDiffs.Add "A" & (i + 1) & "-B" & (foundRow + 1), last3CodeA & " vs " & matchedLast3CodeB
                    versionDiffCount = versionDiffCount + 1
                End If
            End If
        End If
        
        ' 优先级3:编码+C列匹配
        If foundRow = 0 And codeA <> "" And cValueA <> "" Then
            Dim keyCodeCA As String
            keyCodeCA = codeA & "||" & cValueA
            If dictCodeC.Exists(keyCodeCA) Then
                foundRow = dictCodeC(keyCodeCA)
                matchMethod = "编码+C列匹配"
                matchStats("编码+C列匹配") = matchStats("编码+C列匹配") + 1
            End If
        End If
        
        ' 优先级4:前9位编码+C列匹配
        If foundRow = 0 And first9CodeA <> "" And cValueA <> "" Then
            Dim keyFirst9CodeCA As String
            keyFirst9CodeCA = first9CodeA & "||" & cValueA
            If dictFirst9CodeC.Exists(keyFirst9CodeCA) Then
                foundRow = dictFirst9CodeC(keyFirst9CodeCA)
                matchMethod = "前9位编码+C列匹配"
                matchStats("前9位编码+C列匹配") = matchStats("前9位编码+C列匹配") + 1
            End If
        End If
        
        ' 优先级5:C列+D列+I列匹配
        If foundRow = 0 And cValueA <> "" And dValueA <> "" And iValueA <> "" Then
            Dim keyCDIA As String
            keyCDIA = cValueA & "||" & dValueA & "||" & iValueA
            If dictCDI.Exists(keyCDIA) Then
                foundRow = dictCDI(keyCDIA)
                matchMethod = "CDI匹配"
                matchStats("CDI匹配") = matchStats("CDI匹配") + 1
            End If
        End If
        
        ' 优先级6:C列+I列匹配
        If foundRow = 0 And cValueA <> "" And iValueA <> "" Then
            Dim keyCIA As String
            keyCIA = cValueA & "||" & iValueA
            If dictCI.Exists(keyCIA) Then
                foundRow = dictCI(keyCIA)
                matchMethod = "CI匹配"
                matchStats("CI匹配") = matchStats("CI匹配") + 1
            End If
        End If
        
        ' 优先级7:C列匹配
        If foundRow = 0 And cValueA <> "" Then
            If dictC.Exists(cValueA) Then
                foundRow = dictC(cValueA)
                matchMethod = "C列匹配"
                matchStats("C列匹配") = matchStats("C列匹配") + 1
            End If
        End If
        
        ' 处理匹配结果
        If foundRow > 0 Then
            ' 标记已匹配
            If Not matchedRowsB.Exists(foundRow) Then
                matchedRowsB.Add foundRow, True
            End If
            
            ' 对比详细数据
            diffDetails = ""
            Dim hasDiff As Boolean
            hasDiff = False
            
            ' 对比C列
            Dim cValueBCompare As String
            cValueBCompare = TrimText(bData(foundRow, 2))
            If CompareDataAdvanced(cValueA, cValueBCompare) Then
                wsA.Cells(i + 1, 3).Interior.Color = RGB(255, 200, 200)
                wsB.Cells(foundRow + 1, 3).Interior.Color = RGB(200, 255, 200)
                diffDetails = diffDetails & "C"
                hasDiff = True
            End If
            
            ' 对比D列(数量)
            Dim dValueBCompare As String
            dValueBCompare = TrimText(bData(foundRow, 3))
            If CompareDataAdvanced(dValueA, dValueBCompare) Then
                wsA.Cells(i + 1, 4).Interior.Color = RGB(255, 200, 200)
                wsB.Cells(foundRow + 1, 4).Interior.Color = RGB(200, 255, 200)
                diffDetails = diffDetails & IIf(diffDetails = "", "D", "/D")
                hasDiff = True
            End If
            
            ' 对比G列(单位)
            If gValueA <> "" And codeA <> "" Then
                Dim gValueB As String
                gValueB = TrimText(bData(foundRow, 6))
                If CompareDataAdvanced(gValueA, gValueB) Then
                    wsA.Cells(i + 1, 7).Interior.Color = RGB(255, 200, 200)
                    wsB.Cells(foundRow + 1, 7).Interior.Color = RGB(200, 255, 200)
                    diffDetails = diffDetails & IIf(diffDetails = "", "G", "/G")
                    hasDiff = True
                End If
            End If
            
            ' 对比I列
            Dim iValueBCompare As String
            iValueBCompare = TrimText(bData(foundRow, 8))
            If CompareDataAdvanced(iValueA, iValueBCompare) Then
                wsA.Cells(i + 1, 9).Interior.Color = RGB(255, 200, 200)
                wsB.Cells(foundRow + 1, 9).Interior.Color = RGB(200, 255, 200)
                diffDetails = diffDetails & IIf(diffDetails = "", "I", "/I")
                hasDiff = True
            End If
            
            ' 添加对比结果
            If hasDiff Then
                wsA.Cells(i + 1, commentColA).Value = matchMethod & "但有差异[" & diffDetails & "]"
                wsA.Cells(i + 1, commentColA).Interior.Color = GetMatchColor(matchMethod, True)
                
                wsB.Cells(foundRow + 1, commentColB).Value = matchMethod & "但有差异[" & diffDetails & "]"
                wsB.Cells(foundRow + 1, commentColB).Interior.Color = GetMatchColor(matchMethod, False)
                
                diffCount = diffCount + 1
            Else
                wsA.Cells(i + 1, commentColA).Value = matchMethod
                wsA.Cells(i + 1, commentColA).Interior.Color = GetMatchColor(matchMethod, True)
                
                wsB.Cells(foundRow + 1, commentColB).Value = matchMethod
                wsB.Cells(foundRow + 1, commentColB).Interior.Color = GetMatchColor(matchMethod, False)
            End If
            
            ' 添加版本差异提示
            If versionDiffs.Exists("A" & (i + 1) & "-B" & (foundRow + 1)) Then
                Dim versionMsg As String
                versionMsg = "物料版本不同: " & versionDiffs("A" & (i + 1) & "-B" & (foundRow + 1))
                wsA.Cells(i + 1, versionColA).Value = versionMsg
                wsB.Cells(foundRow + 1, versionColB).Value = versionMsg
                wsA.Cells(i + 1, versionColA).Interior.Color = RGB(255, 240, 200)
                wsB.Cells(foundRow + 1, versionColB).Interior.Color = RGB(255, 240, 200)
            End If
        Else
            ' 未找到匹配
            wsA.Cells(i + 1, commentColA).Value = "B文件无对应数据"
            wsA.Cells(i + 1, commentColA).Interior.Color = RGB(255, 220, 180)
            MarkUniqueRow wsA, i + 1, True
            matchStats("未匹配") = matchStats("未匹配") + 1
        End If
        
ContinueLoopA:
    Next i
    ' ========== 阶段4:标记B文件独有数据 ==========
    For i = 1 To UBound(bData, 1)
        If Not matchedRowsB.Exists(i) Then
            wsB.Cells(i + 1, commentColB).Value = "A文件无对应数据"
            wsB.Cells(i + 1, commentColB).Interior.Color = RGB(255, 240, 200)
            MarkUniqueRow wsB, i + 1, False
        End If
    Next i
    
    ' 处理层次关系
    ProcessHierarchySafe wsA, lastRowA
    ProcessHierarchySafe wsB, lastRowB
    
Cleanup:
    ' 恢复设置
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True
    Application.DisplayAlerts = True
    
    ' 调整列宽
    AutoFitColumnsExcludeA wsA, versionColA
    AutoFitColumnsExcludeA wsB, versionColB
    
    ' 高亮差异
    HighlightDifferencesWithComments wsA, lastRowA, commentColA
    HighlightDifferencesWithComments wsB, lastRowB, commentColB
    
    ' 计算总用时
    totalTime = Timer - startTime
    
    ' 生成详细报告
    Dim msg As String
    msg = GenerateReport(lastRowA, lastRowB, indexStats, matchStats, diffCount, versionDiffCount, indexTime, totalTime)
    
    MsgBox msg, vbInformation, "BOM智能对比完成"
    
    ' 保存选项
    Dim response As VbMsgBoxResult
    response = MsgBox("B文件对比结果已标记。是否保存B文件?", vbQuestion + vbYesNo, "保存文件")
    
    If response = vbYes Then
        Dim savePath As String, originalName As String
        originalName = wbB.Name
        savePath = wbB.Path & "\对比结果_" & Replace(originalName, "." & Split(originalName, ".")(UBound(Split(originalName, "."))), "") & ".xlsx"
        
        On Error Resume Next
        wbB.SaveAs savePath, FileFormat:=xlOpenXMLWorkbook
        If Err.Number = 0 Then MsgBox "B文件已保存为:" & vbCrLf & savePath, vbInformation
        On Error GoTo 0
    End If
    
    wbB.Close SaveChanges:=(response = vbYes)
    
    ' 清理对象
    Set dictFullCode = Nothing
    Set dictFirst9Code = Nothing
    Set dictCodeC = Nothing
    Set dictFirst9CodeC = Nothing
    Set dictCDI = Nothing
    Set dictCI = Nothing
    Set dictC = Nothing
    Set matchedRowsB = Nothing
    Set versionDiffs = Nothing
    Set matchStats = Nothing
    
    Exit Sub
    
ErrorHandler:
    MsgBox "错误 " & Err.Number & ": " & Err.Description, vbCritical, "对比失败"
    GoTo Cleanup
End Sub

' ============================================================
' 辅助函数
' ============================================================

' 安全的字符串转换(去除首尾空格)
Function TrimText(ByVal val As Variant) As String
    On Error Resume Next
    If IsError(val) Then
        TrimText = ""
    ElseIf IsNull(val) Then
        TrimText = ""
    ElseIf val = "" Then
        TrimText = ""
    Else
        TrimText = Trim(CStr(val))
    End If
    On Error GoTo 0
End Function

' 获取最后一行
Function GetLastRow(ws As Worksheet, col As Long) As Long
    On Error Resume Next
    GetLastRow = ws.Cells(ws.Rows.Count, col).End(xlUp).Row
    If GetLastRow = 0 Then GetLastRow = 1
    If GetLastRow = 1 And ws.Cells(1, col).Value = "" Then GetLastRow = 1
    On Error GoTo 0
End Function

' 获取最后一列
Function GetLastColumn(ws As Worksheet) As Long
    On Error Resume Next
    GetLastColumn = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
    If GetLastColumn = 0 Then GetLastColumn = 1
    On Error GoTo 0
End Function

' 自动调整列宽(排除A列)
Sub AutoFitColumnsExcludeA(ws As Worksheet, lastCol As Long)
    On Error Resume Next
    ' 记录A列当前宽度
    Dim aColWidth As Double
    aColWidth = ws.Columns("A:A").ColumnWidth
    
    ' 调整B列到最后一列的宽度
    If lastCol > 2 Then
        Dim colRange As Range
        Set colRange = ws.Range(ws.Cells(1, 2), ws.Cells(1, lastCol)).EntireColumn
        colRange.AutoFit
        
        ' 设置对比列宽度
        If lastCol >= 10 Then
            ws.Columns(lastCol - 1).ColumnWidth = 25
        End If
        ws.Columns(lastCol).ColumnWidth = 30
    End If
    
    ' 恢复A列宽度
    ws.Columns("A:A").ColumnWidth = aColWidth
    
    ' 自动调整行高
    ws.Rows.AutoFit
    On Error GoTo 0
End Sub

' 设置对比结果标题
Sub SetupCommentHeaders(ws As Worksheet, col As Long, fileType As String)
    ws.Cells(1, col).Value = "对比结果(" & fileType & ")"
    With ws.Cells(1, col)
        .Font.Bold = True
        .HorizontalAlignment = xlCenter
        .Interior.Color = RGB(200, 200, 200)
        .Borders.LineStyle = xlContinuous
        .Borders.Weight = xlThin
    End With
End Sub

' 设置版本差异标题
Sub SetupVersionHeaders(ws As Worksheet, col As Long, fileType As String)
    ws.Cells(1, col).Value = "版本差异(" & fileType & ")"
    With ws.Cells(1, col)
        .Font.Bold = True
        .HorizontalAlignment = xlCenter
        .Interior.Color = RGB(255, 240, 200)
        .Borders.LineStyle = xlContinuous
        .Borders.Weight = xlThin
    End With
End Sub

' 清除所有格式
Sub ClearAllFormats(ws As Worksheet, lastRow As Long)
    If lastRow > 1 Then
        Dim lastCol As Long
        lastCol = GetLastColumn(ws)
        If lastCol > 0 Then
            With ws.Range(ws.Cells(1, 1), ws.Cells(lastRow, lastCol))
                .ClearFormats
                .Font.Bold = False
                .Font.Color = RGB(0, 0, 0)
                .Interior.ColorIndex = xlNone
            End With
        End If
    End If
End Sub

' 检查是否为完全空行
Function IsCompletelyEmptyRow(ByVal code As String, ByVal cValue As String, _
                             ByVal dValue As String, ByVal gValue As String, _
                             ByVal iValue As String) As Boolean
    If code = "" And cValue = "" And dValue = "" And gValue = "" And iValue = "" Then
        IsCompletelyEmptyRow = True
    Else
        IsCompletelyEmptyRow = False
    End If
End Function

' 检查是否有内容需要对比
Function HasContentToCompare(ByVal code As String, ByVal cValue As String, _
                           ByVal dValue As String, ByVal iValue As String) As Boolean
    If code <> "" Or cValue <> "" Or dValue <> "" Or iValue <> "" Then
        HasContentToCompare = True
    Else
        HasContentToCompare = False
    End If
End Function

' 高级数据对比(忽略首尾空格)
Function CompareDataAdvanced(ByVal val1 As String, ByVal val2 As String) As Boolean
    ' 去除首尾空格
    val1 = Trim(val1)
    val2 = Trim(val2)
    
    If val1 = "" And val2 = "" Then
        CompareDataAdvanced = False
        Exit Function
    End If
    
    If val1 = val2 Then
        CompareDataAdvanced = False
        Exit Function
    End If
    
    ' 处理数字
    If IsNumeric(val1) And IsNumeric(val2) Then
        CompareDataAdvanced = (Abs(CDbl(val1) - CDbl(val2)) > 0.0001)
    Else
        CompareDataAdvanced = (val1 <> val2)
    End If
End Function

' 根据匹配方法获取颜色
Function GetMatchColor(ByVal method As String, ByVal isFileA As Boolean) As Long
    Select Case method
        Case "完全匹配", "完全编码匹配"
            GetMatchColor = RGB(220, 255, 220)  ' 浅绿
        Case "物料版本不同"
            GetMatchColor = RGB(255, 240, 220)  ' 浅橙
        Case "编码+C列匹配"
            GetMatchColor = RGB(220, 240, 255)  ' 浅蓝
        Case "前9位编码+C列匹配"
            GetMatchColor = RGB(240, 220, 255)  ' 浅紫
        Case "CDI匹配"
            GetMatchColor = RGB(255, 240, 220)  ' 浅橙
        Case "CI匹配"
            GetMatchColor = RGB(220, 255, 255)  ' 浅青
        Case "C列匹配"
            GetMatchColor = RGB(255, 220, 240)  ' 浅粉
        Case Else
            GetMatchColor = RGB(220, 255, 220)  ' 默认浅绿
    End Select
End Function

' 标记独有行
Sub MarkUniqueRow(ws As Worksheet, rowNum As Long, isFileA As Boolean)
    If isFileA Then
        ws.Cells(rowNum, 3).Interior.Color = RGB(255, 220, 180)
        ws.Cells(rowNum, 4).Interior.Color = RGB(255, 220, 180)
        ws.Cells(rowNum, 7).Interior.Color = RGB(255, 220, 180)
        ws.Cells(rowNum, 9).Interior.Color = RGB(255, 220, 180)
    Else
        ws.Cells(rowNum, 3).Interior.Color = RGB(255, 240, 200)
        ws.Cells(rowNum, 4).Interior.Color = RGB(255, 240, 200)
        ws.Cells(rowNum, 7).Interior.Color = RGB(255, 240, 200)
        ws.Cells(rowNum, 9).Interior.Color = RGB(255, 240, 200)
    End If
End Sub

' 安全的层次处理
Sub ProcessHierarchySafe(ws As Worksheet, lastRow As Long)
    Dim i As Long
    Dim level As String
    
    For i = 2 To lastRow
        Dim code As String
        code = TrimText(ws.Cells(i, 2))
        If code <> "" Then
            level = TrimText(ws.Cells(i, 1))
            If level <> "" Then
                Dim levelNum As Integer
                levelNum = Len(level) - Len(Replace(level, ".", ""))
                ws.Cells(i, 3).IndentLevel = levelNum
            End If
        End If
    Next i
End Sub

' 高亮显示差异编码
Sub HighlightDifferencesWithComments(ws As Worksheet, lastRow As Long, commentCol As Long)
    Dim i As Long
    
    For i = 2 To lastRow
        If Not IsEmpty(ws.Cells(i, commentCol).Value) Then
            Dim commentText As String
            commentText = CStr(ws.Cells(i, commentCol).Value)
            
            If InStr(commentText, "有差异") > 0 Then
                ws.Cells(i, 2).Font.Bold = True
                ws.Cells(i, 2).Font.Color = RGB(200, 0, 0)
                ws.Cells(i, 2).Interior.Color = RGB(255, 240, 240)
            ElseIf InStr(commentText, "无对应数据") > 0 Then
                ws.Cells(i, 2).Font.Bold = True
                ws.Cells(i, 2).Font.Color = RGB(200, 100, 0)
                ws.Cells(i, 2).Interior.Color = RGB(255, 240, 220)
            ElseIf InStr(commentText, "物料版本不同") > 0 Then
                ws.Cells(i, 2).Font.Bold = True
                ws.Cells(i, 2).Font.Color = RGB(200, 100, 0)
                ws.Cells(i, 2).Interior.Color = RGB(255, 240, 200)
            End If
        End If
    Next i
End Sub

' 生成详细报告
Function GenerateReport(ByVal lastRowA As Long, ByVal lastRowB As Long, _
                       ByRef indexStats() As Long, ByRef matchStats As Object, _
                       ByVal diffCount As Long, ByVal versionDiffCount As Long, _
                       ByVal indexTime As Double, ByVal totalTime As Double) As String
    Dim msg As String
    msg = "? BOM智能对比完成" & vbCrLf & String(50, "=") & vbCrLf
    
    ' 基本统计
    msg = msg & "?? 基本统计:" & vbCrLf
    msg = msg & "A文件行数: " & (lastRowA - 1) & " 行" & vbCrLf
    msg = msg & "B文件行数: " & (lastRowB - 1) & " 行" & vbCrLf
    msg = msg & "跳过行: " & matchStats("跳过") & " 行" & vbCrLf
    msg = msg & "数据差异: " & diffCount & " 处" & vbCrLf
    msg = msg & "版本差异: " & versionDiffCount & " 处" & vbCrLf & vbCrLf
    
    ' 性能统计
    msg = msg & "? 性能统计:" & vbCrLf
    msg = msg & "总用时: " & Format(totalTime, "0.00") & " 秒" & vbCrLf
    msg = msg & "索引建立: " & Format(indexTime, "0.00") & " 秒" & vbCrLf
    msg = msg & "对比用时: " & Format(totalTime - indexTime, "0.00") & " 秒" & vbCrLf & vbCrLf
    
    ' 索引统计
    msg = msg & "?? 索引统计:" & vbCrLf
    msg = msg & "1. 完整编码索引: " & indexStats(1) & " 个" & vbCrLf
    msg = msg & "2. 前9位编码索引: " & indexStats(2) & " 个" & vbCrLf
    msg = msg & "3. 编码+C列索引: " & indexStats(3) & " 个" & vbCrLf
    msg = msg & "4. 前9位编码+C列索引: " & indexStats(4) & " 个" & vbCrLf
    msg = msg & "5. CDI索引: " & indexStats(5) & " 个" & vbCrLf
    msg = msg & "6. CI索引: " & indexStats(6) & " 个" & vbCrLf
    msg = msg & "7. C列索引: " & indexStats(7) & " 个" & vbCrLf & vbCrLf
    
    ' 匹配统计
    msg = msg & "?? 匹配统计:" & vbCrLf
    Dim key As Variant
    For Each key In matchStats.Keys
        If key <> "跳过" Then
            msg = msg & "? " & key & ": " & matchStats(key) & vbCrLf
        End If
    Next key
    msg = msg & "? 未匹配: " & matchStats("未匹配") & vbCrLf & vbCrLf
    
    ' 匹配优先级说明
    msg = msg & "?? 匹配优先级:" & vbCrLf
    msg = msg & "1. 完整12位编码匹配" & vbCrLf
    msg = msg & "2. 前9位编码(类别+物料)匹配" & vbCrLf
    msg = msg & "3. 编码+C列匹配" & vbCrLf
    msg = msg & "4. 前9位编码+C列匹配" & vbCrLf
    msg = msg & "5. C列+D列+I列匹配" & vbCrLf
    msg = msg & "6. C列+I列匹配" & vbCrLf
    msg = msg & "7. C列匹配" & vbCrLf
    
    GenerateReport = msg
End Function


本创作借助腾讯元宝互动完成。

--本站原创,转发需注明出处。

欢迎阅读本文,希望本文对您有所帮助!

本文链接:https://www.2kk8.com/?id=1303

版权声明:本文为原创文章,版权归 user666 所有,欢迎分享本文,转载请保留出处!

内页底部广告(PC版),后台可以自由更改

9KKD.com

9KKD.com

这里的内容可以随意更改,在后台-主题配置中设置。

百度推荐获取地址:http://tuijian.baidu.com/,百度推荐可能会有一些未知的问题,使用中有任何问题请直接联系百度官方客服!
评论框上方广告(PC版),后台可以自由更改

评论(0) 赞助本站

9KKD惠万家

发表评论:


【顶】 【踩】 【好】 【懵】 【赞】 【表情】

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

推荐阅读
11月28日

城市建设话景象

发布 : | 分类 : 创享学习 | 评论 : 0人 | 浏览 : 533次

经过十几年的城市建设,你会发现,所有的城市都变成了一个模样:一个万达十一个吾悦广场。广场旁边永远有这几家店:...