简体   繁体   English

比较两个工作簿

[英]Compare two workbooks

I'm looking to compare the changes between two workbooks.我希望比较两个工作簿之间的变化。
The data looks a little like this数据看起来有点像这样

Workbook 1:工作簿 1:

Column1     Column 2     Column 3   
Nissan      Micra        Red      
Honda       CRV          Grey      
Honda       Accord       Grey 

Workbook 2:练习册 2:

Column 1     Column 2     Column 3  
Nissan       Micra         Red  
Honda        CRV           White  
Honda        CRV           Grey

I want to identify the changes from column to column as I traverse each row.我想在遍历每一行时确定从列到列的变化。

For example, the code should identify / output that in Row 2, there is a change between Column 2 and Column 3, and in Row 3, a change between Column 1 and Column 2.例如,代码应该识别/输出在第 2 行中,第 2 列和第 3 列之间有变化,在第 3 行中,第 1 列和第 2 列之间发生变化。

It's a little difficult to answer your question as it is right now because you didn't give any preliminary code or details of how you want the comparison to be done (via MsgBox, Debug.Print, generating a .xlsx or .txt file, etc.).像现在这样回答你的问题有点困难,因为你没有提供任何初步代码或有关如何完成比较的详细信息(通过 MsgBox、Debug.Print、生成 .xlsx 或 .txt 文件,等等。)。

Luckily, this looks similar to something I had to do in the past, so I have a code example to share with you that can help you get started.幸运的是,这看起来与我过去必须做的事情类似,所以我有一个代码示例与您分享,可以帮助您入门。

To run the example, simply paste the code below (1 sub procedure and 2 functions) in a module and run the sub procedure.要运行该示例,只需将下面的代码(1 个子过程和 2 个函数)粘贴到一个模块中并运行该子过程。

Public Sub CompareWorkbooks()
'PURPOSE: Compare the sheets with the same name in two workbooks to make sure all the values are the same.

    'Select the 2 files manually
    Dim WbName1 As String, WbName2 As String
    WbName1 = UserSelectWorkbook
    WbName2 = UserSelectWorkbook

    'Open the 2 files if they are not open
    Dim FullFileName As String
    Dim temp() As String
    Dim FileName As String

    FullFileName = WbName1
    temp = Split(FullFileName, "\")
    FileName = temp(UBound(temp))

    Dim wb1 As Workbook, wb2 As Workbook

    If IsWorkbookOpen(FileName) = False Then
        Set wb1 = Workbooks.Open(FullFileName)
    Else
        Set wb1 = Workbooks(FileName)
    End If

    FullFileName = WbName2
    temp = Split(FullFileName, "\")
    FileName = temp(UBound(temp))

    If IsWorkbookOpen(FileName) = False Then
        Set wb2 = Workbooks.Open(FullFileName)
    Else
        Set wb2 = Workbooks(FileName)
    End If

    'Compare the 2 files
    Dim DifferenceFoundInWorkbook As Boolean

    Dim ws1 As Worksheet, ws2 As Worksheet
    For Each ws1 In wb1.Worksheets
        For Each ws2 In wb2.Worksheets

            If ws1.Name = ws2.Name Then

                Dim Range1 As Range, Range2 As Range
                Set Range1 = ws1.UsedRange
                Set Range2 = ws2.UsedRange

                Dim DifferenceFoundWithinSheets As Boolean
                DifferenceFoundWithinSheets = False 'Reset

                Dim CellNumber As Long
                CellNumber = 0 'Reset

                Dim c As Range
                For Each c In Range1

                    CellNumber = CellNumber + 1
                    If c.Value2 <> Range2.Cells(CellNumber).Value2 Then

                        Dim DoContinue As Variant
                        DoContinue = MsgBox("Different values in " & vbNewLine & _
                        "[" & wb1.Name & "]" & ws1.Name & "!" & c.Address & " (""" & Range1.Cells(CellNumber).Value2 & """)" & vbNewLine & _
                        "[" & wb2.Name & "]" & ws2.Name & "!" & c.Address & " (""" & Range2.Cells(CellNumber).Value2 & """)" & vbNewLine & vbNewLine & _
                        "Continue searching?", _
                        vbYesNoCancel, "Workbook Comparison")

                        DifferenceFoundWithinSheets = True
                        DifferenceFoundInWorkbook = True

                        Select Case DoContinue
                        Case Is = vbYes: 'Let the comparison continue
                        Case Is = vbNo: Exit Sub
                        Case Is = vbCancel: Exit Sub
                        Case Else: Exit Sub 'For when the user press the X in the top righ corner.
                        End Select

                    End If
                Next c

                If Not DifferenceFoundWithinSheets Then
                    MsgBox "No difference found between the 2 worksheets with name " & ws1.Name
                End If

            End If

        Next ws2
    Next ws1


    If Not DifferenceFoundInWorkbook Then
        MsgBox "No difference found between the 2 workbooks."
    End If

End Sub

Public Function UserSelectWorkbook() As String
'PURPOSE: Allows to select one workbook using the usual window.
'SOURCE: https://excelmacromastery.com/excel-vba-workbook/

    On Error GoTo ErrorHandler

    Dim FD As FileDialog
    Set FD = Application.FileDialog(msoFileDialogFilePicker)

    ' Open the file dialog
    With FD
        ' Set Dialog Title
        .Title = "Please Select File"

        ' Add filter
        .Filters.Add "Excel Files", "*.xls;*.xlsx;*.xlsm;*.xlsb;*.csv"

        ' Allow selection of one file only
        .AllowMultiSelect = False

        ' Display dialog
        .Show

        If FD.SelectedItems.Count <> 0 Then
            UserSelectWorkbook = FD.SelectedItems(1)
        Else
            MsgBox "Selecting a file has been cancelled. "
            UserSelectWorkbook = vbNullString
        End If
    End With

CleanUp:
    Set FD = Nothing
    Exit Function
ErrorHandler:
    MsgBox "Error: " & Err.Description
    GoTo CleanUp

End Function

Public Function IsWorkbookOpen(ByVal FullFileName As String) As Boolean

    Dim wb As Workbook
    Dim ErrNb As Long

    On Error Resume Next
    Set wb = Workbooks(FullFileName)
    ErrNb = Err.Number
    On Error GoTo 0

    Select Case ErrNb
    Case 0:         IsWorkbookOpen = True
    Case Else:      IsWorkbookOpen = False
    End Select

End Function

This code will give you a MsgBox window for each difference found.此代码将为您提供每个找到的差异的 MsgBox 窗口。 You might want to change that to a command that would produce a list of those differences and write them inside a worksheet.您可能希望将其更改为一个命令,该命令将生成这些差异的列表并将它们写入工作表中。

Also note that this macro doesn't have any error handling and isn't optimized to run on very large workbooks.另请注意,此宏没有任何错误处理功能,也未针对在非常大的工作簿上运行进行优化。

EDIT:编辑:

If you want to generate a report into a new workbook, you could use a different version of the CompareWorkbooks macro:如果要在新工作簿中生成报告,可以使用不同版本的CompareWorkbooks宏:

Public Sub CompareWorkbooks()
'PURPOSE: Compare the sheets with the same name in two workbooks and generate a summary in a new workbook.

    'Select the 2 files manually
    Dim WbName1 As String, WbName2 As String
    WbName1 = UserSelectWorkbook
    WbName2 = UserSelectWorkbook

    'Open the 2 files if they are not open
    Dim FullFileName As String
    Dim temp() As String
    Dim FileName As String

    FullFileName = WbName1
    temp = Split(FullFileName, "\")
    FileName = temp(UBound(temp))

    Dim wb1 As Workbook, wb2 As Workbook

    If IsWorkbookOpen(FileName) = False Then
        Set wb1 = Workbooks.Open(FullFileName)
    Else
        Set wb1 = Workbooks(FileName)
    End If

    FullFileName = WbName2
    temp = Split(FullFileName, "\")
    FileName = temp(UBound(temp))

    If IsWorkbookOpen(FileName) = False Then
        Set wb2 = Workbooks.Open(FullFileName)
    Else
        Set wb2 = Workbooks(FileName)
    End If

    'Compare the 2 files
    Dim DifferenceFoundInWorkbook As Boolean

    Dim ws1 As Worksheet, ws2 As Worksheet
    For Each ws1 In wb1.Worksheets
        For Each ws2 In wb2.Worksheets

            If ws1.Name = ws2.Name Then

                Dim Range1 As Range, Range2 As Range
                Set Range1 = ws1.UsedRange
                Set Range2 = ws2.UsedRange

                Dim DifferenceFoundWithinSheets As Boolean
                DifferenceFoundWithinSheets = False 'Reset

                Dim CellNumber As Long
                CellNumber = 0 'Reset

                Dim c As Range
                For Each c In Range1

                    CellNumber = CellNumber + 1
                    If c.Value2 <> Range2.Cells(CellNumber).Value2 Then

                        Dim Counter As Long

                        Dim wbReport As Workbook
                        If Counter = 0 Then
                            Set wbReport = Workbooks.Add
                        End If

                        Counter = Counter + 1

                        wbReport.ActiveSheet.Cells(Counter, 1).Value2 = "[" & wb1.Name & "]" & ws1.Name & "!" & c.Address & " (""" & Range1.Cells(CellNumber).Value2 & """)"
                        wbReport.ActiveSheet.Cells(Counter, 2).Value2 = "[" & wb2.Name & "]" & ws2.Name & "!" & c.Address & " (""" & Range2.Cells(CellNumber).Value2 & """)"

                        DifferenceFoundInWorkbook = True

                    End If
                Next c

            End If

        Next ws2
    Next ws1


    If Not DifferenceFoundInWorkbook Then
        MsgBox "No difference found between the 2 workbooks."
    End If

End Sub

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM