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

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

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

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

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

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

总字数:44018

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

功能特点:

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


使用方法:

以第2行的物料编码,做两个文件的数据对比。

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

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

BOM.jpg

Sub CompareBOMFilesWithComments()
    Dim wbA As Workbook, wbB As Workbook
    Dim wsA As Worksheet, wsB As Worksheet
    Dim lastRowA As Long, lastRowB As Long
    Dim dict As Object
    Dim i As Long, j As Long
    Dim keyA As String, keyB As String
    Dim foundRow As Long
    Dim startTime As Double
    Dim hasDiff As Boolean
    Dim diffDetails As String
    
    startTime = Timer
    On Error GoTo ErrorHandler
    
    Set dict = CreateObject("Scripting.Dictionary")
    
    Set wbA = ThisWorkbook
    Set wsA = wbA.Sheets(1)
    
    ' 获取B文件,支持所有Excel格式
    Dim fileFilter As String
    fileFilter = "Excel文件 (*.xls;*.xlsx;*.xlsm;*.xlsb),*.xls;*.xlsx;*.xlsm;*.xlsb"
    
    Dim filePathB As String
    filePathB = Application.GetOpenFilename(fileFilter, , "请选择B文件(支持.xls/.xlsx/.xlsm/.xlsb格式)")
    If filePathB = "False" Then Exit Sub
    
    ' 检测文件扩展名
    Dim fileExt As String
    fileExt = LCase(Right(filePathB, 4))
    
    ' 根据文件类型设置打开模式
    Dim readOnlyMode As Boolean
    Dim updateLinks As Boolean
    
    readOnlyMode = True
    updateLinks = False
    
    ' 特殊处理.xls文件
    If fileExt = ".xls" Then
        Set wbB = Workbooks.Open(filePathB, UpdateLinks:=updateLinks, ReadOnly:=readOnlyMode)
    Else
        Set wbB = Workbooks.Open(filePathB, UpdateLinks:=updateLinks, ReadOnly:=readOnlyMode)
    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 Then
        MsgBox "A文件没有数据或B列为空,请检查文件格式。", vbExclamation
        GoTo Cleanup
    End If
    
    If lastRowB <= 1 Then
        MsgBox "B文件没有数据或B列为空,请检查文件格式。", vbExclamation
        GoTo Cleanup
    End If
    
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False
    Application.DisplayAlerts = False
    
    ' 清除之前格式
    ClearAllFormats wsA, lastRowA
    ClearAllFormats wsB, lastRowB
    
    ' 添加对比结果列
    Dim commentColA As Long, commentColB As Long
    commentColA = GetLastColumn(wsA) + 1
    commentColB = GetLastColumn(wsB) + 1
    
    ' 设置对比结果标题
    SetupCommentHeaders wsA, commentColA, "A"
    SetupCommentHeaders wsB, commentColB, "B"
    
    ' 创建B文件索引字典(只包含非空编码)
    Dim rowCountB As Long
    rowCountB = 0
    
    For i = 2 To lastRowB
        keyB = GetSafeCellValue(wsB.Cells(i, 2))
        
        If keyB <> "" Then
            If Not dict.Exists(keyB) Then
                dict.Add keyB, i
                rowCountB = rowCountB + 1
            Else
                ' 重复编码标记
                wsB.Cells(i, commentColB).Value = "编码重复"
                wsB.Cells(i, commentColB).Interior.Color = RGB(255, 200, 200)
            End If
        End If
    Next i
    
    ' 创建A文件索引字典用于双向查找(只包含非空编码)
    Dim dictA As Object
    Set dictA = CreateObject("Scripting.Dictionary")
    
    For i = 2 To lastRowA
        keyA = GetSafeCellValue(wsA.Cells(i, 2))
        If keyA <> "" Then
            If Not dictA.Exists(keyA) Then
                dictA.Add keyA, i
            Else
                ' 重复编码标记
                wsA.Cells(i, commentColA).Value = "编码重复"
                wsA.Cells(i, commentColA).Interior.Color = RGB(255, 200, 200)
            End If
        End If
    Next i
    
    Dim matchCount As Long, diffCount As Long
    Dim uniqueCountA As Long, uniqueCountB As Long
    matchCount = 0
    diffCount = 0
    uniqueCountA = 0
    uniqueCountB = 0
    
    ' 对比A文件数据
    For i = 2 To lastRowA
        keyA = GetSafeCellValue(wsA.Cells(i, 2))
        
        ' 跳过空编码行
        If keyA = "" Then
            GoTo ContinueLoopCompareA
        End If
        
        If dict.Exists(keyA) Then
            foundRow = dict(keyA)
            matchCount = matchCount + 1
            
            diffDetails = ""
            hasDiff = False
            
            ' 对比C列:子件名称
            If CompareCellsAdvanced(wsA.Cells(i, 3), wsB.Cells(foundRow, 3)) Then
                wsA.Cells(i, 3).Interior.Color = RGB(255, 200, 200) ' 浅红色
                wsB.Cells(foundRow, 3).Interior.Color = RGB(200, 255, 200) ' 浅绿色
                diffDetails = diffDetails & "C"
                hasDiff = True
            End If
            
            ' 对比D列:单位用量
            If CompareCellsAdvanced(wsA.Cells(i, 4), wsB.Cells(foundRow, 4)) Then
                wsA.Cells(i, 4).Interior.Color = RGB(255, 200, 200)
                wsB.Cells(foundRow, 4).Interior.Color = RGB(200, 255, 200)
                diffDetails = diffDetails & IIf(diffDetails = "", "D", "/D")
                hasDiff = True
            End If
            
            ' 对比G列:位号
            If CompareCellsAdvanced(wsA.Cells(i, 7), wsB.Cells(foundRow, 7)) Then
                wsA.Cells(i, 7).Interior.Color = RGB(255, 200, 200)
                wsB.Cells(foundRow, 7).Interior.Color = RGB(200, 255, 200)
                diffDetails = diffDetails & IIf(diffDetails = "", "G", "/G")
                hasDiff = True
            End If
            
            ' 对比I列:注释信息
            If CompareCellsAdvanced(wsA.Cells(i, 9), wsB.Cells(foundRow, 9)) Then
                wsA.Cells(i, 9).Interior.Color = RGB(255, 200, 200)
                wsB.Cells(foundRow, 9).Interior.Color = RGB(200, 255, 200)
                diffDetails = diffDetails & IIf(diffDetails = "", "I", "/I")
                hasDiff = True
            End If
            
            ' 添加对比结果注释
            If hasDiff Then
                wsA.Cells(i, commentColA).Value = "B文件有差异[" & diffDetails & "]"
                wsA.Cells(i, commentColA).Interior.Color = RGB(255, 240, 200) ' 浅橙色背景
                
                wsB.Cells(foundRow, commentColB).Value = "A文件有差异[" & diffDetails & "]"
                wsB.Cells(foundRow, commentColB).Interior.Color = RGB(220, 240, 255) ' 浅蓝色背景
                
                diffCount = diffCount + 1
            Else
                wsA.Cells(i, commentColA).Value = "一致"
                wsA.Cells(i, commentColA).Interior.Color = RGB(220, 255, 220) ' 浅绿色背景
                
                wsB.Cells(foundRow, commentColB).Value = "一致"
                wsB.Cells(foundRow, commentColB).Interior.Color = RGB(220, 255, 220)
            End If
            
        Else
            ' A文件独有编码
            wsA.Cells(i, commentColA).Value = "B文件无此编码"
            wsA.Cells(i, commentColA).Interior.Color = RGB(255, 220, 180) ' 橙色背景
            
            ' 标记A文件整行
            MarkUniqueRow wsA, i, True
            uniqueCountA = uniqueCountA + 1
        End If
        
ContinueLoopCompareA:
    Next i
    
    ' 标记B文件独有编码
    For i = 2 To lastRowB
        keyB = GetSafeCellValue(wsB.Cells(i, 2))
        
        ' 跳过空编码行
        If keyB = "" Then
            GoTo ContinueLoopCompareB
        End If
        
        If Not dictA.Exists(keyB) Then
            ' B文件独有编码
            wsB.Cells(i, commentColB).Value = "A文件无此编码"
            wsB.Cells(i, commentColB).Interior.Color = RGB(255, 240, 200) ' 浅橙色背景
            
            ' 标记B文件整行
            MarkUniqueRow wsB, i, False
            uniqueCountB = uniqueCountB + 1
        End If
        
ContinueLoopCompareB:
    Next i
    
    ' 处理层次关系
    ProcessHierarchySafe wsA, lastRowA
    ProcessHierarchySafe wsB, lastRowB
    
Cleanup:
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True
    Application.DisplayAlerts = True
    
    ' 自动调整列宽(排除A列)
    AutoFitColumnsExcludeA wsA, commentColA
    AutoFitColumnsExcludeA wsB, commentColB
    
    ' 高亮显示差异编码
    HighlightDifferencesWithComments wsA, lastRowA, commentColA
    HighlightDifferencesWithComments wsB, lastRowB, commentColB
    
    ' 清理对象
    Set dict = Nothing
    Set dictA = Nothing
    
    ' 计算实际参与对比的行数
    Dim actualRowsA As Long, actualRowsB As Long
    actualRowsA = 0
    actualRowsB = 0
    
    For i = 2 To lastRowA
        If GetSafeCellValue(wsA.Cells(i, 2)) <> "" Then actualRowsA = actualRowsA + 1
    Next i
    
    For i = 2 To lastRowB
        If GetSafeCellValue(wsB.Cells(i, 2)) <> "" Then actualRowsB = actualRowsB + 1
    Next i
    
    ' 显示结果统计
    Dim msg As String
    msg = "? 对比完成!" & vbCrLf & vbCrLf & _
          "?? 文件统计:" & vbCrLf & _
          "A文件总行数: " & (lastRowA - 1) & " 行" & vbCrLf & _
          "A文件有效行: " & actualRowsA & " 行" & vbCrLf & _
          "B文件总行数: " & (lastRowB - 1) & " 行" & vbCrLf & _
          "B文件有效行: " & actualRowsB & " 行" & vbCrLf & vbCrLf & _
          "?? 对比结果:" & vbCrLf & _
          "编码匹配: " & matchCount & " 个" & vbCrLf & _
          "数据差异: " & diffCount & " 处" & vbCrLf & _
          "A文件独有: " & uniqueCountA & " 个" & vbCrLf & _
          "B文件独有: " & uniqueCountB & " 个" & vbCrLf & vbCrLf & _
          "?? 用时: " & Format(Timer - startTime, "0.00") & " 秒" & vbCrLf & vbCrLf & _
          "?? 颜色说明:" & vbCrLf & _
          "?? 红色: A文件与B文件不同的数据" & vbCrLf & _
          "?? 绿色: B文件与A文件不同的数据" & vbCrLf & _
          "?? 橙色: 编码不存在于另一文件" & vbCrLf & _
          "?? 蓝色: 一致的数据"
    
    MsgBox msg, vbInformation, "BOM文件对比完成"
    
    ' 激活A文件窗口
    wbA.Activate
    
    ' 可选:询问是否保存B文件
    Dim response As VbMsgBoxResult
    response = MsgBox("B文件对比结果已标记。" & vbCrLf & _
                      "是否保存B文件?", vbQuestion + vbYesNo, "保存文件")
    
    If response = vbYes Then
        Dim savePath As String
        Dim 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
        End If
        On Error GoTo 0
    End If
    
    ' 关闭B文件
    wbB.Close SaveChanges:=(response = vbYes)
    
    Exit Sub
    
ErrorHandler:
    MsgBox "错误 " & Err.Number & ": " & Err.Description & vbCrLf & _
           "请检查文件格式和内容。", vbCritical, "对比失败"
    GoTo Cleanup
End Sub

' 获取最后一行
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

' 自动调整列宽(排除A列)
Sub AutoFitColumnsExcludeA(ws As Worksheet, lastCol As Long)
    On Error Resume Next
    
    ' 为A列设置固定宽度
    ws.Columns("A:A").ColumnWidth = 8
    
    ' 调整B列到最后一列的宽度
    If lastCol > 2 Then
        Dim colRange As Range
        Set colRange = ws.Range(ws.Cells(1, 2), ws.Cells(1, lastCol)).EntireColumn
        colRange.AutoFit
        
        ' 设置对比结果列宽度
        ws.Columns(lastCol).ColumnWidth = 20
    End If
    
    ' 自动调整行高
    ws.Rows.AutoFit
    
    On Error GoTo 0
End Sub

' 获取最后一列
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

' 设置对比结果标题
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 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 GetSafeCellValue(cell As Range) As String
    On Error Resume Next
    If IsError(cell.Value) Then
        GetSafeCellValue = ""
    ElseIf IsNull(cell.Value) Then
        GetSafeCellValue = ""
    ElseIf cell.Value = "" Then
        GetSafeCellValue = ""
    Else
        GetSafeCellValue = Trim(CStr(cell.Value))
    End If
    On Error GoTo 0
End Function

' 高级单元格比较
Function CompareCellsAdvanced(cell1 As Range, cell2 As Range) As Boolean
    Dim val1 As String, val2 As String
    
    val1 = GetSafeCellValue(cell1)
    val2 = GetSafeCellValue(cell2)
    
    ' 处理数字和文本
    If IsNumeric(val1) And IsNumeric(val2) Then
        CompareCellsAdvanced = (CDbl(val1) <> CDbl(val2))
    Else
        CompareCellsAdvanced = (val1 <> val2)
    End If
End Function

' 标记独有行
Sub MarkUniqueRow(ws As Worksheet, rowNum As Long, isFileA As Boolean)
    If isFileA Then
        ' A文件独有 - 橙色
        ws.Cells(rowNum, 3).Interior.Color = RGB(255, 220, 180) ' C列
        ws.Cells(rowNum, 4).Interior.Color = RGB(255, 220, 180) ' D列
        ws.Cells(rowNum, 7).Interior.Color = RGB(255, 220, 180) ' G列
        ws.Cells(rowNum, 9).Interior.Color = RGB(255, 220, 180) ' I列
    Else
        ' B文件独有 - 浅橙色
        ws.Cells(rowNum, 3).Interior.Color = RGB(255, 240, 200) ' C列
        ws.Cells(rowNum, 4).Interior.Color = RGB(255, 240, 200) ' D列
        ws.Cells(rowNum, 7).Interior.Color = RGB(255, 240, 200) ' G列
        ws.Cells(rowNum, 9).Interior.Color = RGB(255, 240, 200) ' I列
    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
        ' 只处理有编码的行
        If GetSafeCellValue(ws.Cells(i, 2)) <> "" Then
            level = GetSafeCellValue(ws.Cells(i, 1))
            
            If level <> "" Then
                ' 计算层级深度
                Dim levelNum As Integer
                levelNum = Len(level) - Len(Replace(level, ".", ""))
                
                ' 为子件名称添加缩进
                ws.Cells(i, 3).IndentLevel = levelNum
                
                ' 为层次列添加样式
                With ws.Cells(i, 1)
                    .Font.Bold = (levelNum = 0) ' 一级层次加粗
                    Select Case levelNum
                        Case 0: .Font.Color = RGB(0, 0, 150) ' 深蓝色
                        Case 1: .Font.Color = RGB(0, 100, 0) ' 深绿色
                        Case 2: .Font.Color = RGB(150, 0, 0) ' 深红色
                        Case 3: .Font.Color = RGB(100, 0, 100) ' 紫色
                        Case 4: .Font.Color = RGB(0, 100, 100) ' 深青色
                        Case 5: .Font.Color = RGB(100, 100, 0) ' 橄榄色
                    End Select
                End With
            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 commentText = "编码重复" Then
                ws.Cells(i, 2).Font.Bold = True
                ws.Cells(i, 2).Font.Color = RGB(150, 0, 150)
                ws.Cells(i, 2).Interior.Color = RGB(240, 220, 240)
            ElseIf commentText = "一致" Then
                ws.Cells(i, 2).Font.Color = RGB(0, 100, 0)
            End If
        End If
    Next i
End Sub


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

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

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

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

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

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

9KKD.com

9KKD.com

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

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

评论(0) 赞助本站

9KKD惠万家

发表评论:


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

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

推荐阅读
11月28日

城市建设话景象

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

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