Reputation: 11
I am comparing 2 worksheets based on a key and write the results in the new workbook. KEY column is A.
2 workbooks are Todays and yesterdays file.
I need to compare todays file with yesterdays file. Below are my scenarios:
If KEY matches in both the Worksheets and if all the columns of that corresponding KEY matches that is from (B:E) , then in F column the value should be NO CHANGE
If KEY matches in both the Worksheets and if any of the columns does not match corresponding to the KEY (B:E), then F column should have value CHANGED
If KEY does not match then F column should have value NEW RECORD
Below is my code writing logic is overriding my values and they are writing records from my yesterdays file instead if todays file :
'ASSUMPTIONS:
'Data begins in cell A1 of each worksheet
'Data is continuous (does not have blank rows or columns)
'Comparison Key should be in column A of each sheet and should NEVER be blank
Sub CompareArrays()
Dim BookOne As String, BookTwo As String, BookThree As String
Dim WorkbookOne As Workbook, WorkbookTwo As Workbook, WorkbookThree As Workbook
Dim SheetOne As Worksheet, SheetTwo As Worksheet, SheetThree As Worksheet
Dim Keytocompare1 As String
Dim Keytocompare2 As String
Dim Keytocompare3 As String
Dim Keytocompare4 As String
Dim Keytocompare5 As String
Sheet1.Cells.ClearContents
'Select Path for First Workbook
MsgBox "Select Today's Common Customer File"
With Application.FileDialog(msoFileDialogFilePicker)
.AllowMultiSelect = False
.Title = "SELECT BOOK ONE"
.Show
BookOne = .SelectedItems(1)
End With
'Select Path for Second Workbook
MsgBox "Select Yesterday's Common Customer File"
With Application.FileDialog(msoFileDialogFilePicker)
.AllowMultiSelect = False
.Title = "SELECT BOOK TWO"
.Show
BookTwo = .SelectedItems(1)
End With
'Select Path for Output Workbook
MsgBox "Select Output Common Customer File"
With Application.FileDialog(msoFileDialogFilePicker)
.AllowMultiSelect = False
.Title = "SELECT BOOK THREE"
.Show
BookThree = .SelectedItems(1)
End With
Application.Workbooks.Open BookOne
Set SheetOne = ActiveWorkbook.Worksheets("Sheet1") '
Application.Workbooks.Open BookTwo
Set SheetTwo = ActiveWorkbook.Worksheets("Sheet1") '
Application.Workbooks.Open BookThree
Set SheetThree = ActiveWorkbook.Worksheets("Sheet1") '
Windows("Today.xlsx").Activate
Sheets("Sheet1").Select
Range("A1").Select
Do While ActiveCell.Value <> ""
Keytocompare1 = ActiveCell.Value
Keytocompare2 = ActiveCell.Offset(0, 1).Value
Keytocompare3 = ActiveCell.Offset(0, 2).Value
Keytocompare4 = ActiveCell.Offset(0, 3).Value
Keytocompare5 = ActiveCell.Offset(0, 4).Value
Windows("yesterday.xlsx").Activate
Sheets("Sheet1").Select
Range("A1").Select
Do While ActiveCell.Value <> ""
If ActiveCell.Value = Keytocompare1 Then
If ((ActiveCell.Offset(0, 1).Value = Keytocompare2) And (ActiveCell.Offset(0, 2).Value = Keytocompare3) And (ActiveCell.Offset(0, 3).Value = Keytocompare4) And (ActiveCell.Offset(0, 4).Value = Keytocompare5)) Then
Windows("Output.xlsx").Activate
Sheets("Sheet1").Select
Range("A1").Select
ActiveCell.Offset(0, 1).Value = Keytocompare2
ActiveCell.Offset(0, 2).Value = Keytocompare3
ActiveCell.Offset(0, 3).Value = Keytocompare4
ActiveCell.Offset(0, 4).Value = Keytocompare5
ActiveCell.Offset(0, 5).Value = "No Change"
Else
Windows("Output.xlsx").Activate
Sheets("Sheet1").Select
Range("A1").Select
ActiveCell.Offset(0, 1).Value = Keytocompare2
ActiveCell.Offset(0, 2).Value = Keytocompare3
ActiveCell.Offset(0, 3).Value = Keytocompare4
ActiveCell.Offset(0, 4).Value = Keytocompare5
ActiveCell.Offset(0, 5).Value = "Change"
End If
Else
Windows("Output.xlsx").Activate
Sheets("Sheet1").Select
Range("A1").Select
ActiveCell.Offset(0, 1).Value = Keytocompare2
ActiveCell.Offset(0, 2).Value = Keytocompare3
ActiveCell.Offset(0, 3).Value = Keytocompare4
ActiveCell.Offset(0, 4).Value = Keytocompare5
ActiveCell.Offset(0, 5).Value = "New Record"
End If
Windows("Yesterday.xlsx").Activate
Sheets("Sheet1").Select
' Range("A2").Select
ActiveCell.Offset(1, 0).Select
Loop
Windows("Today.xlsx").Activate
Sheets("Sheet1").Select
' Range("A2").Select
ActiveCell.Offset(1, 0).Select
Loop
End Sub
Could you guys help out in correcting this ?
Upvotes: 0
Views: 4205
Reputation: 2278
give this a try
'ASSUMPTIONS:
'Data begins in cell A1 of each worksheet
'Data is continuous (does not have blank rows or columns)
'Comparison Key should be in column A of each sheet and should NEVER be blank
Sub CompareArrays()
' Sheet1.Cells.ClearContents ' *********** UNKNOWN SHEET
Dim filePick As FileDialog ' set up filePicker object
Set filePick = Application.FileDialog(msoFileDialogFilePicker)
filePick.AllowMultiSelect = False
MsgBox "Select Today's Common Customer File"
filePick.Title = "SELECT BOOK ONE"
filePick.Show
Dim todayBookName As String
todayBookName = filePick.SelectedItems(1)
MsgBox "Select Yesterday's Common Customer File"
filePick.Title = "SELECT BOOK TWO"
filePick.Show
Dim yesterBookName As String
yesterBookName = filePick.SelectedItems(1)
MsgBox "Select Output Common Customer File"
filePick.Title = "SELECT BOOK THREE"
filePick.Show
Dim outputBookName As String
outputBookName = filePick.SelectedItems(1)
Set filePick = Nothing
Dim todayBook As Workbook
todayBook = Application.Workbooks.Open(todayBookName)
Dim yesterBook As Workbook
yesterBook = Application.Workbooks.Open(yesterBookName)
Dim outputBook As Workbook
outputBook = Application.Workbooks.Open(outputBookName)
' -------------------- process workbooks -----------------
Dim recordStatus As String
Dim yesterCell As Range
Dim outputCell As Range
Dim keyToCompare As Variant
Dim i As Integer
Dim todayCell As Range
Set todayCell = todayBook.Sheets("Sheet1").Range("A1") ' set pointer to cell A1
Do While todayCell.Value <> ""
keyToCompare = todayCell.Resize(1, 6).Value ' copy row of cells ... one extra cell at end
keyToCompare = Application.Transpose(keyToCompare) ' convert to
keyToCompare = Application.Transpose(keyToCompare) ' single dimension array
Set yesterCell = yesterBook.Sheets("Sheet1").Range("A1") ' set pointer to cell A1
Do While yesterCell.Value <> "" ' process all non-blank cells
Set outputCell = outputBook.Sheets("Sheet1").Range("A1") ' set pointer to cell A1
If yesterCell.Value = keyToCompare(1) Then
If ( _
(yesterCell.Offset(0, 1).Value = keyToCompare(2)) _
And (yesterCell.Offset(0, 2).Value = keyToCompare(3)) _
And (yesterCell.Offset(0, 3).Value = keyToCompare(4)) _
And (yesterCell.Offset(0, 4).Value = keyToCompare(5))) Then
recordStatus = "No Change"
Else
recordStatus = "Change"
End If
Else
recordStatus = "New Record"
End If
keyToCompare(6) = recordStatus
For i = 1 To 5 ' update 5 cells in output workbook
outputCell.Offset(0, i).Value = keyToCompare(i + 1)
Next i
Set yesterCell = yesterCell.Offset(1, 0) ' move pointer one cell down
Set outputCell = outputCell.Offset(1, 0) ' this is missing from original code
Loop
Set todayCell = todayCell.Offset(1, 0)
Loop
End Sub
Upvotes: 1
Reputation: 692
I put together a sample VBA code (tested also) assuming all 3 sheets are in current workbook. You can make necessary changes and adjustments to set to your workbooks and worksheets. I have used combination of Excel Formulas and 2 dimensional Arrays to read data from Excel and write back to Excel. Keep in mind, when you read from Excel into 2-d array, lower bound of array is 1, but when you write back to Excel you would need to initiate 0 based array (both for rows and columns).
Public Sub CompareSheets()
Dim wb As Workbook, xlRng As Range
Dim ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet
Dim Ar1, Ar2, Ar3, ArLoad()
Dim lstR1!, lstR2!, iRow!, nRow!, str1$, str2$
Set wb = ThisWorkbook
Set ws1 = wb.Sheets(1): Set ws2 = wb.Sheets(2): Set ws3 = wb.Sheets(3)
' Get the last non blank cell in Column A in 1st and 2nd worksheets
Set xlRng = ws3.Cells(1, 1)
With xlRng
.FormulaR1C1 = "=MAX((" & ws1.Name & "!C1<>"""")*(ROW(" & ws1.Name & "!C1)))"
.FormulaArray = .Formula: .Calculate: lstR1 = .Value2
.FormulaR1C1 = "=MAX((" & ws2.Name & "!C1<>"""")*(ROW(" & ws2.Name & "!C1)))"
.FormulaArray = .Formula: .Calculate: lstR2 = .Value2
.Clear
End With
' Load into 2-d array data 1st and 2nd sheets
Ar1 = ws1.Range("A1:E" & lstR1).Value
Ar2 = ws2.Range("A1:E" & lstR2).Value
' Load Row number of 1st sheet that matches current row of second sheet
Set xlRng = ws3.Range("A1:A" & lstR2)
With xlRng
.FormulaR1C1 = "=IFERROR(MATCH(" & ws2.Name & "!RC," & ws1.Name & "!C,0),0)"
.Calculate: Ar3 = .Value: .Clear
End With
ReDim Preserve ArLoad(lstR2 - 1, 5) ' this is the array that will be loaded into 3rd worksheet
For iRow = 1 To UBound(Ar3, 1)
For nCol = 1 To 5
ArLoad(iRow - 1, nCol - 1) = Ar2(iRow, nCol) ' Load ArLoad with data from ws2
Next nCol
' Load Last Column of ArLoad with respective value depending if there is a change o
If Ar3(iRow, 1) > 0 Then
nRow = Ar3(iRow, 1) ' matching row number of 1st worksheet
str2 = Ar2(iRow, 2) & Ar2(iRow, 3) & Ar2(iRow, 4) & Ar2(iRow, 5)
str1 = Ar1(nRow, 2) & Ar1(nRow, 3) & Ar1(nRow, 4) & Ar1(nRow, 5)
If str1 = str2 Then
ArLoad(iRow - 1, 5) = "NO CHANGE"
Else
ArLoad(iRow - 1, 5) = "CHANGED"
End If
Else
ArLoad(iRow - 1, 5) = "NEW RECORD"
End If
Next iRow
ws3.Range("A1:F" & lstR2).Value = ArLoad
End Sub
Upvotes: 0