比较两个文件中的两个 Excel 工作表

问题描述 投票:0回答:1

我正在尝试比较两个 Excel 文件:

  • PO 文件.xlsx
  • 库存文件.xlsx

每个文件包含一个带有以下列的工作表
商品代码、商品名称、数量
我想将库存文件中的数量与 PO 文件中的数量进行比较(从客户处收到 PO,并检查其中的物品是否有库存(库存))

Inventory

我有以下代码。

Sub CrossCheckInventoryPO()
    Dim InventoryWs As Worksheet
    Dim POWs As Worksheet
    Dim InventoryFileName As Variant
    Dim POFileName As Variant
    Dim CommonColumn As String
    Dim LastRow As Long

    ' Prompt the user to select the inventory file
    InventoryFileName = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*")
    If InventoryFileName = "False" Then Exit Sub
    
    ' Prompt the user to select the PO file
    POFileName = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*")
    If POFileName = "False" Then Exit Sub
    
    ' Set the common column header (e.g., "item code")
    CommonColumn = "Qty" ' Change this to match your actual column header
    
    ' Set the worksheets for inventory and PO
    Set InventoryWs = Workbooks.Open(InventoryFileName).Worksheets(1)
    Set POWs = Workbooks.Open(POFileName).Worksheets(1)
    
    ' Find the last row in the inventory and PO worksheets
    LastRow = InventoryWs.Cells(InventoryWs.Rows.Count, CommonColumn).End(xlUp).Row
    
    
    ' Loop through each row in the inventory worksheet
    For i = 2 To LastRow ' Assuming headers are in row 1
        ' Get the value from the common column in the inventory sheet
        Dim InventoryValue As Variant
        InventoryValue = InventoryWs.Cells(i, CommonColumn).Value
        
        ' Use VLOOKUP to find the corresponding value in the PO sheet
        Dim POValue As Variant
        On Error Resume Next ' Ignore errors temporarily
        POValue = Application.VLookup(InventoryValue, POWs.Range(CommonColumn & ":" & CommonColumn), 3, False)
        On Error GoTo 0 ' Reset error handling
        
        ' Check if an error occurred during the VLOOKUP
        If IsError(POValue) Then
            ' Do something when the value is not found in the PO sheet
            ' For example, highlight the row in red or display a message
            InventoryWs.Rows(i).Interior.Color = RGB(255, 0, 0) ' Red color
        End If
    Next i
    
    ' Close the inventory and PO workbooks without saving changes
    InventoryWs.Parent.Close SaveChanges:=False
    POWs.Parent.Close SaveChanges:=False
    
    ' Inform the user that the process is complete
    MsgBox "Cross-checking completed!", vbInformation
End Sub

采购订单文件中存在但库存文件中不存在的项目应以红色突出显示。
另外,库存文件中可用但数量少于 PO 文件中的数量也应突出显示(可能采用不同的颜色)。

excel vba
1个回答
1
投票

您的代码即将完成。

变化

  • CommonColumn = "C"
    公共列应该是列名(索引)而不是标题名
  • 确保
    VLookup
    的第二个参数从A列开始。
  • 应用黄色突出显示表示库存水平较低。
  • 循环查看 PO 工作表,根据库存验证数量
  • 突出显示并保存 PO 文件。
Option Explicit

Sub CrossCheckInventoryPO()
    Dim InventoryWs As Worksheet
    Dim POWs As Worksheet
    Dim InventoryFileName As Variant
    Dim POFileName As Variant
    Dim CommonColumn As String
    Dim LastRow As Long
    ' Prompt the user to select the inventory file
    InventoryFileName = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*")
    If InventoryFileName = "False" Then Exit Sub
    ' Prompt the user to select the PO file
    POFileName = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*")
    If POFileName = "False" Then Exit Sub
    ' Set the common column header (e.g., "item code")
    CommonColumn = "C" ' **
    ' Set the worksheets for inventory and PO
    Set InventoryWs = Workbooks.Open(InventoryFileName).Worksheets(1)
    Set POWs = Workbooks.Open(POFileName).Worksheets(1)
    ' Find the last row in the inventory and PO worksheets
    LastRow = POWs.Cells(POWs.Rows.Count, CommonColumn).End(xlUp).Row
    ' Loop through each row in the inventory worksheet
    For i = 2 To LastRow ' Assuming headers are in row 1
        ' Get the value from the common column in the inventory sheet
        Dim InventoryValue As Variant
        Dim POValue As Variant
        POValue = POWs.Cells(i, CommonColumn).Value
        ' Use VLOOKUP to find the corresponding value in the PO sheet
        On Error Resume Next ' Ignore errors temporarily
        InventoryValue = Application.VLookup(InventoryValue, POWs.Range("A:" & CommonColumn), 3, False)
        On Error GoTo 0 ' Reset error handling
        ' Check if an error occurred during the VLOOKUP
        If IsError(InventoryValue) Then
            ' Do something when the value is not found in the PO sheet
            ' For example, highlight the row in red or display a message
            POWs.Rows(i).Interior.Color = RGB(255, 0, 0) ' Red color
        ElseIf POValue > InventoryValue Then ' **
            POWs.Rows(i).Interior.Color = RGB(255, 255, 0) ' Yellow color ' **'
        End If
    Next i
    ' Close the inventory and PO workbooks without saving changes
    InventoryWs.Parent.Close SaveChanges:=False ' **'
    POWs.Parent.Close SaveChanges:=True
    ' Inform the user that the process is complete
    MsgBox "Cross-checking completed!", vbInformation
End Sub

利用Dictionary对象来提高效率。

  1. 将所有数据加载到数组中。
  2. 实施突出显示规则:
  • 对于没有库存的情况,以红色突出显示 PO。
  • 对于库存较低的情况,对采购订单和库存应用黄色突出显示。
Option Explicit
Sub CrossCheckInventoryPO()
    Dim InventoryWs As Worksheet
    Dim POWs As Worksheet
    Dim InventoryFileName As Variant
    Dim POFileName As Variant
    Dim CommonColumn As String
    Dim LastRow As Long, i as Long
    Dim arrInv, arrPO, objDic
    InventoryFileName = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*")
    If InventoryFileName = "False" Then Exit Sub
    POFileName = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*")
    If POFileName = "False" Then Exit Sub
    CommonColumn = "C" 
    Set InventoryWs = Workbooks.Open(InventoryFileName).Worksheets(1)
    Set POWs = Workbooks.Open(POFileName).Worksheets(1)
    ' Clean highligh
    InventoryWs.Cells.Interior.Pattern = xlNone
    POWs.Cells.Interior.Pattern = xlNone
    set objDic = CreateObject("scripting.dictionary")    
    ' Loading inventory data
    LastRow = InventoryWs.Cells(InventoryWs.Rows.Count, CommonColumn).End(xlUp).Row
    arrInv = InventoryWs.Range("A1:" & CommonColumn & LastRow).Value
    For i = 2 To LastRow 
        objDic(arrInv(i,1)) = Array(Val(arrInv(i,3)), i)
    Next
    ' Loading PO data
    LastRow = POWs.Cells(POWs.Rows.Count, CommonColumn).End(xlUp).Row
    arrPO = POWs.Range("A1:" & CommonColumn & LastRow).Value
    Dim sKey As Variant
    For i = 2 To LastRow         
        sKey = arrPO(i,1)
        If objDic.Exists(sKey) Then
            ' Inventory exist
            If arrPO(i, 3) > objDic(sKey)(0) Then
                ' Low inventory
                POWs.Rows(i).Interior.Color = RGB(255, 255, 0) 
                InventoryWs.Rows(objDic(sKey)(1)).Interior.Color = RGB(255, 255, 0) 
            End IF
        Else
            ' No inventory
            POWs.Rows(i).Interior.Color = RGB(255, 0, 0) 
        End If
    Next i
    ' Save workbook
    InventoryWs.Parent.Close SaveChanges:=True 
    POWs.Parent.Close SaveChanges:=True
    MsgBox "Cross-checking completed!", vbInformation
End Sub

© www.soinside.com 2019 - 2024. All rights reserved.