How can I open and define two Excel files in VBA? - vba

As a part of a bigger macro, and need to open and define two workbooks and sheets (I am aware of that I define my worksheets as Variant, I need this for future operations). I get a mistake when I try to set value to SheetRI. What can it be?
Sub compareQRTsAll()
Dim ActiveWb As Workbook
Dim ActiveSh As Worksheet
Dim SheetFasit As Variant
Dim SheetRI As Variant
Dim FolderFasit As String
Dim FileFasit As String
Dim FolderRI As String
Dim FileRI As String
Dim WbFasit As Workbook
Dim WbRI As Workbook
Dim WbFasitPath As String
Dim strRangeToCheck As String
Dim nShFasit As Integer
Dim nShRI As Integer
Dim iRow As Long
Dim iCol As Long
Dim i As Integer
Dim j As Integer
i = 2
j = 6
Set ActiveWb = ActiveWorkbook
Set ActiveSh = ActiveWb.Worksheets(1)
strRangeToCheck = "A1:AAA1000"
ActiveSh.Range("A2:D10000").Clear
FolderFasit = ActiveSh.Range("J6")
FolderRI = ActiveSh.Range("J7")
Do While ActiveSh.Cells(j, 8) <> ""
FileFasit = Dir(FolderFasit & "\*" & ActiveSh.Cells(j, 8) & "*.xls*")
Set WbFasit = Workbooks.Open(Filename:=FolderFasit & "\" & FileFasit)
SheetFasit = WbFasit.Worksheets(1).Range(strRangeToCheck)
nShFasit = WbFasit.Sheets.Count
FileRI = Dir(FolderRI & "\*" & ActiveSh.Cells(j, 8) & "*.xls*")
Set WbRI = Workbooks.Open(Filename:=FolderRI & "\" & FileRI)
SheetRI = WbRI.Worksheets(1).Range(strRangeToCheck) '<-------------THIS DOESN'T WORK
nShRI = WbRI.Sheets.Count
If nShFasit <> nShRI Then
MsgBox "QRT " & ActiveSh.Cells(j, 8) & " has different number of sheets in fasit and in RI. Further check will not be performed"
ElseIf nShFasit = nShRI And nShFasit = 1 Then
For iRow = LBound(SheetFasit, 1) To UBound(SheetFasit, 1)
For iCol = LBound(SheetFasit, 2) To UBound(SheetFasit, 2)
If SheetFasit(iRow, iCol) = SheetRI(iRow, iCol) Then
' Do nothing.
Else
ActiveSh.Cells(i, 1) = "Check row " & iRow & ", column " & iCol & " in " & ActiveSh.Cells(j, 8)
ActiveSh.Cells(i, 2) = SheetFasit(iRow, iCol)
ActiveSh.Cells(i, 3) = SheetRI(iRow, iCol)
i = i + 1
End If
Next iCol
Next iRow
End If
'close workbooks
Dim wb As Workbook
For Each wb In Workbooks
If Not wb Is ActiveWb Then
wb.Close SaveChanges:=False
End If
Next wb
j = j + 1
Loop
End Sub

The problem was in range strRangeToCheck = "A1:AAA1000". Some of my files are saved as .xls, and there is no AAA column on Excel 2003.
Dim FolderRI As String
Dim FileRI As String
Dim WbFasit As Workbook
Dim WbRI As Workbook
Dim WbFasitPath As String
Dim strRangeToCheck As String
Dim nShFasit As Integer
Dim nShRI As Integer
Dim iRow As Long
Dim iCol As Long
Dim i As Integer
Dim j As Integer
i = 2
j = 6
Set ActiveWb = ActiveWorkbook
Set ActiveSh = ActiveWb.Worksheets(1)
strRangeToCheck = "A1:IV1000"
ActiveSh.Range("A2:D10000").Clear
' If you know the data will only be in a smaller range, reduce the size of the ranges above.
'FolderFasit = InputBox("Enter path to the forder with correct QRTs")
'FolderRI = InputBox("Enter path to the forder with QRTs from RI")
FolderFasit = ActiveSh.Range("J6")
FolderRI = ActiveSh.Range("J7")
Do While ActiveSh.Cells(j, 8) <> ""
FileFasit = Dir(FolderFasit & "\*" & ActiveSh.Cells(j, 8) & "*.xls*")
Set WbFasit = Workbooks.Open(Filename:=FolderFasit & "\" & FileFasit)
SheetFasit = WbFasit.Worksheets(1).Range(strRangeToCheck)
nShFasit = WbFasit.Sheets.Count
FileRI = Dir(FolderRI & "\*" & ActiveSh.Cells(j, 8) & "*.xls*")
Set WbRI = Workbooks.Open(Filename:=FolderRI & "\" & FileRI)
Debug.Print FileRI
SheetRI = WbRI.Worksheets(1).Range(strRangeToCheck)
nShRI = WbRI.Sheets.Count
If nShFasit <> nShRI Then
MsgBox "QRT " & ActiveSh.Cells(j, 8) & " has different number of sheets in fasit and in RI. Further check will not be performed"
ElseIf nShFasit = nShRI And nShFasit = 1 Then
For iRow = LBound(SheetFasit, 1) To UBound(SheetFasit, 1)
For iCol = LBound(SheetFasit, 2) To UBound(SheetFasit, 2)
If SheetFasit(iRow, iCol) = SheetRI(iRow, iCol) Then
' Do nothing.
Else
ActiveSh.Cells(i, 1) = "Check row " & iRow & ", column " & iCol & " in " & ActiveSh.Cells(j, 8)
ActiveSh.Cells(i, 2) = SheetFasit(iRow, iCol)
ActiveSh.Cells(i, 3) = SheetRI(iRow, iCol)
i = i + 1
End If
Next iCol
Next iRow
End If
'close workbooks
Dim wb As Workbook
For Each wb In Workbooks
If Not wb Is ActiveWb Then
wb.Close SaveChanges:=False
End If
Next wb
j = j + 1
Loop
End Sub

Related

VBA to export selected row values of excel to csv

I have a requirement for VBA, wherein, If I select a cell in excel, it will export that entire row values to csv.
I have tried
Sub WriteCSVFile()
Dim My_filenumber As Integer
Dim logSTR As String
My_filenumber = FreeFile
logSTR = logSTR & Cells(1, "A").Value & " , "
logSTR = logSTR & Cells(2, "A").Value & " , "
logSTR = logSTR & Cells(3, "A").Value & " , "
logSTR = logSTR & Cells(4, "A").Value
Open "C:\Users\xxxxx\Desktop\Sample.csv" For Append As #My_filenumber
Print #My_filenumber, logSTR
Close #My_filenumber
End Sub
If the range selection can be made dynamic, it can solve the purpose.
Export Selection Rows to CSV
Sub ExportRowsToCSV()
Const FILE_PATH_RIGHT As String = "\Desktop\Sample.csv"
Const FIRST_CELL_ADDRESS As String = "A2"
Const ColDelimiter As String = "," ' or ";"
Const RowDelimiter As String = vbLf
If ActiveSheet Is Nothing Then Exit Sub ' no visible workbook open
If Not TypeOf ActiveSheet Is Worksheet Then Exit Sub ' not a worksheet
If Not TypeOf Selection Is Range Then Exit Sub ' not a range selected
Dim FilePath As String
FilePath = Environ("USERPROFILE") & FILE_PATH_RIGHT
' or:
'FilePath = Environ("OneDrive") & FILE_PATH_RIGHT
Dim drg As Range: Set drg = Selection
Dim ws As Worksheet: Set ws = drg.Worksheet
Dim srg As Range
With ws.UsedRange
Dim lCell As Range: Set lCell = .Cells(.Rows.Count, .Columns.Count)
Set srg = ws.Range(FIRST_CELL_ADDRESS, lCell)
End With
Dim rg As Range: Set rg = Intersect(srg, drg)
If rg Is Nothing Then Exit Sub
Set rg = Intersect(srg, rg.EntireRow)
If rg Is Nothing Then Exit Sub
Dim dLen As Long: dLen = Len(ColDelimiter)
Dim rString As String
Dim rrg As Range
Dim cell As Range
For Each rrg In rg.Rows
For Each cell In rrg.Cells
rString = rString & CStr(cell.Value) & ColDelimiter
Next cell
rString = Left(rString, Len(rString) - dLen) & RowDelimiter
Next rrg
rString = Left(rString, Len(rString) - Len(RowDelimiter))
Dim TextFile As Long: TextFile = FreeFile
Open FilePath For Append As #TextFile
Print #TextFile, rString
Close #TextFile
MsgBox "Row(s) exported.", vbInformation
End Sub
Here I got the code to copy the "values in the entire row where the cell is active" and paste to csv file.
'''
Sub xlRangeToCSVFile()
Dim myWB As Workbook
Dim rngToSave As Range
Dim fNum As Integer
Dim csvVal As String
Dim i As Integer
Set myWB = ThisWorkbook
csvVal = ""
fNum = FreeFile
Set rngToSave = Range("A" & ActiveCell.Row & ":J" & ActiveCell.Row)
Open "C:\Users\xxxxx\Desktop\Sample.csv" For Output As #fNum
i = 1
For j = 1 To rngToSave.Columns.Count
csvVal = csvVal & Chr(34) & rngToSave(i, j).Value & Chr(34) & ","
Next
Print #fNum, Left(csvVal, Len(csvVal) - 1)
csvVal = ""
Close #fnum
End Sub
'''

Create folders using 2 column values from Excel

So I need to make a whole bunch of folders from a spreadsheet.
I have in column A the Surname and in Column B the name of a person, I need to generate folders based on this.
I have found a bit of code that someone else posted, that works, but I need to add a space between the name and surname in the created folder.
The original poster said that they did manage to add a space, but never indicated how.
Sub MakeFoldersForEachRow()
Dim Rng As Range
Dim maxRows, maxCols, r, c As Integer
Dim s As String
Set Rng = Selection
maxRows = Rng.Rows.Count
maxCols = Rng.Columns.Count
For r = 1 To maxRows
s = ""
For c = 1 To maxCols
s = s & Rng(r, c)
Next c
If Len(Dir(ActiveWorkbook.Path & "\" & s, vbDirectory)) = 0 Then
MkDir (ActiveWorkbook.Path & "\" & s)
On Error Resume Next
End If
Next r
End Sub
Please, try the next code:
Sub createFoldNamesFromTwoColumns()
Dim sh As Worksheet, lastR As Long, fldName As String, i As Long
Set sh = ActiveSheet 'use here your necessary sheet
lastR = sh.Range("A" & sh.Rows.count).End(xlUp).row
For i = 1 To lastR
fldName = sh.Range("A" & i) & " " & sh.Range("B" & i)
If Dir(ActiveWorkbook.Path & "\" & fldName, vbDirectory) = "" Then
MkDir ActiveWorkbook.Path & "\" & fldName
End If
Next i
End Sub
Edited:
I could see now your last request, meaning to process the selected columns:
Sub createFoldNamesFromTwoSelectedColumns()
Dim sh As Worksheet, rngSel As Range, C1 As Long, lastR As Long, fldName As String, i As Long
Set sh = ActiveSheet
Set rngSel = Selection
If rngSel.Columns.count <> 2 Then MsgBox "You must select two columns!": Exit Sub
C1 = rngSel.cells(1).Column: Stop
lastR = sh.cells(sh.Rows.count, C1).End(xlUp).row
For i = 1 To lastR
fldName = sh.cells(i, C1) & " " & sh.cells(i, C1 + 1)
If Dir(ActiveWorkbook.Path & "\" & fldName, vbDirectory) = "" Then
MkDir ActiveWorkbook.Path & "\" & fldName
End If
Next i
End Sub

In VBA replace hard coded cell reference with dynamic in a link

I have two workbooks one "database" and another "source". What I'm trying to achieve is to set up a loop that would iterate thru a known range in "source" wb and create links in "database". Data in the "source" wb = C7:C38.
Any ideas?
Code below is the one i'm using to pull single values for the links - how can I make it loop thru range C7:C38?
Option Explicit
'**********Using ip address to link/locate folders in the the directory.
Public Sub PullData()
Dim repDate As Date
Dim tmpFileStr As String
Dim tmpPathStr As String
Dim rowCtrLng As Long
Dim startRowCtrLng As Long
Dim stoptRowCtrLng As Long
Dim msgStr As String
Dim currentDate As Date
Dim stopDate
Dim fldName As String
Dim fName As String
Dim fDay As String
'On Error GoTo errHandler
'Initialize row counter
startRowCtrLng = 2
'Get starting row for new data
Do While ThisWorkbook.ActiveSheet.Range("B" & startRowCtrLng).Value <> ""
startRowCtrLng = startRowCtrLng + 1
Loop
rowCtrLng = startRowCtrLng
'Assign current date to variable
'Pause automatic calculation
Application.Calculation = xlCalculationManual
'Disable alerts
Application.DisplayAlerts = False
repDate = Format(ThisWorkbook.Worksheets("Database").Range("A" & rowCtrLng).Value, "mm/dd/yyyy")
currentDate = Date
fldName = Format(Year(Now), "0000")
fName = Format(Month(Now), "00")
fDay = Format(Day(Now), "0")
'Begin looping through date range
Do While repDate < currentDate
tmpFileStr = ""
tmpPathStr = ""
'Determine if report exists
tmpPathStr = "\\0.0.0.0\dept\Folder\Subfolder\" & fldName & "\"
If Dir("\\0.0.0.0\dept\Folder\Subfolder\" & fldName & "\" & fName & "-" & fldName & ".xls") <> "" Then
tmpFileStr = fName & "-" & fldName & ".xls"
Else
tmpFileStr = ""
End If
If tmpFileStr <> "" Then
'build Links
'Production Date
ThisWorkbook.ActiveSheet.Range("A" & rowCtrLng).Value = repDate
'Crush
ThisWorkbook.ActiveSheet.Range("B" & rowCtrLng).Value = "='" & tmpPathStr & "[" & tmpFileStr & "]C vol'!$C$7"
End If
rowCtrLng = rowCtrLng + 1
repDate = ThisWorkbook.Worksheets("Database").Range("A" & rowCtrLng).Value
Loop
End Sub
'

Automatically Generate CSVs based on cell data

I have the following code which generates a csv file.
Sub WriteCSVFile()
Dim My_filenumber As Integer
Dim logSTR As String
My_filenumber = FreeFile
logSTR = logSTR & Cells(1, "A").Value & " , "
logSTR = logSTR & Cells(2, "A").Value & " , "
logSTR = logSTR & Cells(3, "A").Value & " , "
logSTR = logSTR & Cells(4, "A").Value
Open "D:\BIG DATA\VBA\Sample.csv" For Append As #My_filenumber
Print #My_filenumber, logSTR
Close #My_filenumber
End Sub
This just pulls the top 4 values from the sheets and puts them in a CSV, I now need to modify it to do 2 things, one generate multiple CSVs one for each unique value in column A and then pull values from column B based on column A.
For example:-
Column A contains set A, set B, set C - Set A has 3 tables in column B and I want this to be copied across to the new CSV but I want this to happen for all the sets automatically.
Any help would be greatly appreciated, even a point to another answer?
I am assuming that you want to Print the contents of each Table to the associated Set.
Sub WriteCSVFile2()
Const RootPath As String = "C:\Data Files\Sample_"
Const KillOldFiles As Boolean = True
Dim My_filenumber As Integer
Dim FileName As String
Dim rw As Range
Dim tbls As Collection
Dim tbl As ListObject
Set tbls = getAllTables
My_filenumber = FreeFile
If KillOldFiles Then
For Each rw In Sheet1.ListObjects("SourceTable").DataBodyRange.Rows
FileName = RootPath & rw.Cells(1, 1) & ".csv"
If Len(Dir(FileName)) Then Kill FileName
Next
End If
For Each rw In Sheet1.ListObjects("SourceTable").DataBodyRange.Rows
FileName = RootPath & rw.Cells(1, 1) & ".csv"
Debug.Print FileName
On Error Resume Next
Set tbl = tbls.Item(rw.Cells(1, 2))
If Not tbl Is Nothing Then
Open FileName For Append As #My_filenumber
Print #My_filenumber, getDataBodyRangeCSV(tbl)
Close #My_filenumber
End If
Set tbl = Nothing
On Error GoTo 0
Next
End Sub
Function getDataBodyRangeCSV(tbl As ListObject) As String
Dim c As Range, rw As Range
Dim tr As String, result As String
For Each rw In tbl.DataBodyRange.Rows
For Each c In rw.Cells
tr = tr & c.value & ","
Next
result = result & Left(tr, Len(tr) - 1) & vbCrLf
tr = ""
Next
getDataBodyRangeCSV = Left(result, Len(result) - 1)
End Function
Function getAllTables() As Collection
Dim lists As Collection
Dim tbl As ListObject
Dim ws As Worksheet
Set lists = New Collection
For Each ws In ThisWorkbook.Worksheets
For Each tbl In ws.ListObjects
On Error Resume Next
lists.Add tbl, tbl.Name
On Error GoTo 0
Next
Next
Set getAllTables = lists
End Function
Update: You don't need the more complex example but I am going to leave it. It may be helpful to future viewers.
Cahnge these variables
SouceWorkSheet: The name of the worksheet that your list is on
KillOldFiles: Do you want to delete the old files
arColumns = Array(1, 2, 9, 10): Add the column numbers that you want to export to this array. You just nned to use WriteCSVFile3.
Sub WriteCSVFile3()
Const SouceWorkSheet As String = "Source"
Const RootPath As String = "C:\Data Files\Sample_"
Const KillOldFiles As Boolean = True
Dim My_filenumber As Integer
Dim FileName As String, tr As String
Dim lastRow As Long, x As Long, y
Dim arColumns As Variant
arColumns = Array(1, 2, 9, 10)
My_filenumber = FreeFile
With Worksheets(SouceWorkSheet)
lastRow = .Range("A" & Rows.Count).End(xlUp).Row
If KillOldFiles Then
For x = 2 To lastRow
FileName = RootPath & .Cells(x, 1) & ".csv"
If Len(Dir(FileName)) Then Kill FileName
Next
End If
For x = 2 To lastRow
FileName = RootPath & .Cells(x, 1) & ".csv"
Open FileName For Append As #My_filenumber
For y = 0 To UBound(arColumns)
tr = tr & .Cells(x, arColumns(y)).value & ","
Next
Print #My_filenumber, Left(tr, Len(tr) - 1)
Close #My_filenumber
tr = ""
Next
End With
End Sub
Can't you use something like this ?
Dim OutputFileNum As Integer
OutputFileNum = FreeFile
Open "file.csv" For Output Lock Write As #OutputFileNum
Print #OutputFileNum, "Field1" & "," & "Field2"
SheetValues = Sheets("Sheet1").Range("A1:H9").Value
Dim LineValues() As Variant
ReDim LineValues(1 To 2)
For RowNum = 1 To 9
For ColNum = 1 To 2
LineValues(ColNum) = SheetValues(RowNum, ColNum)
Next
Line = Join(LineValues, ",")
Print #OutputFileNum, Line
Next
Close OutputFileNum

Comparing two worksheets with different column order

I'm trying to compare two worksheets in excel to find new/updated records using vba.
(assume worksheet 1 is old, and worksheet 2 has the potential new/updated entries)
These sheets have very similar information stored in each, just in a different order.
For example:
Worksheet 1 has Street Address in Column E whereas Worksheet 2 has the street Address in Column H. There are many other columns like this.
I'm not really sure where to start. I tried to rearrange the columns in the second sheet by cutting and inserting to match those of the first, but that got out of hand very quickly.
Also, if its a new record, it needs be appended to the end of the data.
**Updated to allow defining the 'key' column. Just change the line 'iKeyCol = 2' to the desired column.
Here is some code to try. I was too lazy to rework all the code I was using, so some of this may be extra for you. Make sure your workbook
1. Has at least three sheets (names 'Sheet1, Sheet2, NewSheet')
2. Has column headers for Sheet1 & Sheet2
3. Col1 must match in both sheets
4. Column count must match in both sheets.
Other that col1, other columns can be in any order.
Paste the code into a new module and the execute.
Let me know if you have a problem.
Option Explicit
' This module will compare differences between two worksheets.
Sub Compare106thWorksheets()
Dim iKeyCol As Integer
'>>>> CHANGE THE FOLLOWING LINE TO IDENTIFY THE KEY COLUMN
iKeyCol = 2
Dim i, i2, i3 As Integer
Dim iRow As Long
Dim iR1, iR2 As Long
Dim iC1, iC2 As Integer
Dim iColMap(30) As Integer
Dim iCol1, iCol2 As Integer
Dim LastRow1 As Long, LastRow2 As Long
Dim LastCol1 As Integer, LastCol2 As Integer
Dim MaxRow1 As Long
Dim MaxCol1 As Integer
Dim sFld1 As String, sFld2 As String
Dim sFN1, sFN2 As String
Dim rptWB As Workbook
Dim DiffCount As Long
Dim iLastRow, iLastColumn As Integer
Dim strDeleted, strInserted As String
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim wsChg As Worksheet
Dim iCHGRows As Long
Dim iCHGCols As Long
Application.ScreenUpdating = False
Application.StatusBar = "Creating the report..."
Set ws1 = ThisWorkbook.Worksheets("Sheet1")
Set ws2 = ThisWorkbook.Worksheets("Sheet2")
Set wsChg = ThisWorkbook.Worksheets("NewSheet")
With ws1.UsedRange ' Get used range of Sheet1
LastRow1 = .Rows.Count
LastCol1 = .Columns.Count
End With
With ws2.UsedRange ' Get used range of Sheet1
LastRow2 = .Rows.Count
LastCol2 = .Columns.Count
End With
With wsChg.UsedRange ' Get used range of Sheet1
iCHGRows = .Rows.Count
iCHGCols = LastCol1
End With
MaxRow1 = LastRow1
MaxCol1 = LastCol1
Debug.Print ws1.Name & " has " & LastRow1 & " rows and " & LastCol1 & " columns."
Debug.Print ws2.Name & " has " & LastRow2 & " rows and " & LastCol2 & " columns."
If MaxRow1 < LastRow2 Then MaxRow1 = LastRow2
If MaxCol1 < LastCol2 Then MaxCol1 = LastCol2
' Build a column map. Require both sheets to have the same names - but different order.
For i = 1 To 30
iColMap(i) = 0
Next i
For iC1 = 1 To MaxCol1
For i = 1 To LastCol2
If ws1.Cells(1, iC1) = ws2.Cells(1, i) Then
iColMap(iC1) = i
Exit For
End If
Next i
Next iC1
' Check if any column headers failed to match.
For i = 1 To MaxCol1
If iColMap(i) = 0 Then
MsgBox "Column named '" & ws1.Cells(1, i) & " not found in Sheet2. Please correct and start again."
GoTo Exit_Code
End If
Next i
strDeleted = "": strInserted = ""
iR2 = 1
DiffCount = 0
For iR1 = 1 To MaxRow1
If ws1.Cells(iR1, iKeyCol) <> ws2.Cells(iR2, iKeyCol) Then ' Cell is different - is it an ADD or Delete?
Debug.Print "Row: " & iR1 & vbTab & ws1.Cells(iR1, iKeyCol) & vbTab & "versus: " & ws2.Cells(iR2, iKeyCol)
sFld1 = Trim(ws1.Cells(iR1, iKeyCol).FormulaLocal)
sFld2 = Trim(ws2.Cells(iR2, iKeyCol).FormulaLocal)
If sFld1 < sFld2 Then
Debug.Print "Deleted Row " & ws1.Cells(iR1, iKeyCol)
DiffCount = DiffCount + 1
wsChg.Cells(DiffCount, iKeyCol) = "Deleted:"
wsChg.Cells(DiffCount, 2) = ws1.Cells(iR1, iKeyCol)
strDeleted = strDeleted & ws1.Cells(iR1, iKeyCol) & vbCrLf
iCHGRows = iCHGRows + 1
wsChg.Cells(iCHGRows, 1) = Now()
For i = 1 To LastCol1
wsChg.Cells(iCHGRows, i + 1) = ws1.Cells(iR1, i)
Next i
ws1.Rows(iR1).EntireRow.Delete
iR1 = iR1 - 1
GoTo Its_OK
ElseIf sFld1 > sFld2 Then
Debug.Print "Inserted Row " & ws2.Cells(iR1, iKeyCol)
Debug.Print "R1: " & iR1 & " R2: " & iR2 & vbTab & ws1.Cells(iR1, iKeyCol) & vbTab & "versus: " & ws2.Cells(iR2, iKeyCol)
DiffCount = DiffCount + 1
strInserted = strInserted & ws2.Cells(iR2, iKeyCol) & vbCrLf
ws1.Rows(iR1).EntireRow.Insert
For i = 1 To LastCol1
ws1.Cells(iR1, i) = ws2.Cells(iR2, iColMap(i))
Next i
iR2 = iR2 + 1
GoTo Its_OK
Else
iR2 = iR2 + 1
End If
Else ' Values are the same
iR2 = iR2 + 1
End If
Its_OK:
Next iR1
Debug.Print "Deleted:"
Debug.Print strDeleted
Debug.Print "------------------------------------------------------------------"
Debug.Print "Inserted:"
Debug.Print strInserted
Debug.Print "------------------------------------------------------------------"
For iRow = 2 To LastRow2
Application.StatusBar = "Comparing cells " & Format(iCol1 / MaxCol1, "0 %") & "..."
For iCol1 = 1 To LastCol1
iCol2 = iColMap(iCol1)
sFld1 = ""
sFld2 = ""
On Error Resume Next
sFld1 = ws1.Cells(iRow, iCol1).FormulaLocal
sFld2 = ws2.Cells(iRow, iCol2).FormulaLocal
On Error GoTo 0
If sFld1 <> sFld2 Then
Debug.Print "Row: " & iRow & vbTab & ws1.Cells(iRow, iCol1) & vbTab & "versus: " & ws2.Cells(iRow, iCol2)
DiffCount = DiffCount + 1
wsChg.Cells(DiffCount, 1) = ws1.Cells(iRow, iKeyCol)
wsChg.Cells(DiffCount, 2) = ws1.Cells(1, iCol1)
wsChg.Cells(DiffCount, 3) = sFld1
wsChg.Cells(DiffCount, 4) = sFld2
ws1.Cells(iRow, iCol1).FormulaLocal = ws2.Cells(iRow, iCol2).FormulaLocal
End If
Next iCol1
Next iRow
wsChg.Activate
Application.StatusBar = "Formatting the report..."
With Range(Cells(1, 1), Cells(MaxRow1, MaxCol1))
.Interior.ColorIndex = 19
With .Borders(xlEdgeTop)
.LineStyle = xlContinuous
.Weight = xlHairline
End With
With .Borders(xlEdgeRight)
.LineStyle = xlContinuous
.Weight = xlHairline
End With
With .Borders(xlEdgeLeft)
.LineStyle = xlContinuous
.Weight = xlHairline
End With
With .Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.Weight = xlHairline
End With
On Error Resume Next
With .Borders(xlInsideHorizontal)
.LineStyle = xlContinuous
.Weight = xlHairline
End With
With .Borders(xlInsideVertical)
.LineStyle = xlContinuous
.Weight = xlHairline
End With
On Error GoTo 0
End With
Columns("A:IV").ColumnWidth = 20
MsgBox DiffCount & " cells contain different formulas!", vbInformation, _
"Compare " & ws1.Name & " with " & ws2.Name
Exit_Code:
Application.StatusBar = False
Application.ScreenUpdating = True
End Sub