Run-time error on finding last used column - vba

I Have an excel VBA code to merge sheets in workbooks of a folder.First it wants to copy all cells to output sheet from the first sheet.Next sheet onwards, it wants to copy from the 2nd row till last used row.The column headings of input sheets may not be in same order.It is showing an automation error on debugging the below line for finding last used column
**lco = ws2.Cells(1, Columns.Count).End(xlToLeft).Column**
the entire code is following:
Application.ScreenUpdating = False
directory = "C:\Users\Desktop\MYExcel\Input\"
fileName = Dir(directory & "*.xl??")
i = 0
j = 0
'create new output file
Set Wk = Workbooks.Add
With Wk
.Title = "All Sheets"
.SaveAs fileName:="C:\Users\Desktop\MYExcel\Output\AllSheets.xlsx"
.Close
End With
Do While fileName <> ""
If i = 0 Then
Set x = Workbooks.Open(directory & fileName) 'Opening the first workbook in directory
Set y = Workbooks.Open("C:\Users\Desktop\MYExcel\Output\AllSheets.xlsx") 'opening the output workbook
Set ws2 = y.Sheets(1)
If j = 0 Then
Set ws1 = x.Sheets(1)
With ws1
.Cells.Copy ws2.Cells 'Copying all cells to output sheet for s
y.Close True
'x.Close False
End With
j = j + 1
End If
If j > 0 Then
For Each sheet In x.Worksheets
'Set ws2 = y.Sheets(1)
' lColumn = ws.Cells(1, Columns.Count).End(xlToLeft).Column
lci = sheet.Cells(1, Columns.Count).End(xlToLeft).Column
**lco = ws2.Cells(1, Columns.Count).End(xlToLeft).Column**
lri = sheet.Range("A65536").End(xlUp).Row
lro = ws2.Range("A65536").End(xlUp).Row
For Each cell In rng
For Each cell2 In rng2
l = ActiveCell.Column
If cell.Value = cell2.Value Then
With sheet
.Cells(cell, 2).EntireColumn.Copy ws2.Cells(cell2).Range(lro)
End With
End If
Next cell2
Next cell
Next sheet
End If
Workbooks(directory & fileName).Close
fileName = Dir()
i = i + 1
Else
Set d = Workbooks.Open(directory & fileName)
Set f = Workbooks.Open("AllSheets.xls*")
'Windows("Book3.xlsm").Activate
For Each sheet In x.Worksheets
Set ws4 = f.Sheets(1)
lci = sheet.Cells(1, sheet.Columns.Count).End(xlToLeft).Column
lco = ws4.Cells(1, ws4.Columns.Count).End(xlToLeft).Column
lri = sheet.Range("A65536").End(xlUp).Row
lro = ws4.Range("A65536").End(xlUp).Row
Set rng = sheet.Range("A1:A" & lci)
Set rng2 = ws4.Range("A1:A" & lco)
For Each cell In rng
For Each cell2 In rng2
l = ActiveCell.Column
If cell.Value = cell2.Value Then
With sheet
.Cells(cell, 2).EntireColumn.Copy ws4.Cells(cell2).Range(lro)
End With
End If
Next cell2
Next cell
Next sheet
End If
Loop

Code you have used to get LastColumn is absolutely fine. It is working at my end.
Only you need to check that you have commented the line
Set ws2 = y.Sheets(1)
Please uncomment the same and check, it must work.

Related

Copy one cell and paste down a column

Been trying to figure out how to copy a cell from worksheet A and paste it down a column in Worksheet B until it matches the same amount of rows as an adjacent column. Take the following screenshot for example. How would I properly accomplish this in VBA? Been trying to figure this out for a while now. All I've been able to do is copy the cell and paste it adjacent to the last cell in the adjacent column instead of down the entire column. The worksheet I'm copying data from is pictured below.
Copy From SpreadSheet down below
Paste to SpreadSheet down below
Current Code
Sub pullSecEquipment()
Dim path As String
Dim ThisWB As String
Dim wbDest As Workbook
Dim shtDest As Worksheet
Dim shtPull As Worksheet
Dim Filename As String
Dim Wkb As Workbook
Dim CopyRng As Range, DestRng As Range
Dim lRow As Integer
Dim destLRow As Integer
Dim Lastrow As Long
Dim FirstRow As Long
Dim UpdateDate As String
ThisWB = ActiveWorkbook.Name
Dim selectedFolder
With Application.FileDialog(msoFileDialogFolderPicker)
.Show
selectedFolder = .SelectedItems(1) & "\"
End With
path = selectedFolder
Application.EnableEvents = False
Application.ScreenUpdating = False
Set shtDest = Workbooks("GPnewchapterTEST2.xlsm").Worksheets("START")
'clear content of destination table
shtDest.Rows("8:" & Rows.Count).ClearContents
Filename = Dir(path & "\*.xls*", vbNormal)
If Len(Filename) = 0 Then Exit Sub
Do Until Filename = vbNullString
Set Wkb = Workbooks.Open(Filename:=path & "\" & Filename)
'MsgBox Filename
'''''
'SEC
'''''
If InStr(Filename, "Equipment") <> 0 Then
Dim range1 As Range
Set range1 = Range("E:K")
'For Each Wkb In Application.Workbooks
'For Each shtDest In Wkb.Worksheets
'Set shtPull = Wkb.Sheets(1)
'If shtPull.Name Like "*-*" Then
'last row
destLRow = Wkb.Sheets(1).Cells.Find(what:="*", SearchOrder:=xlRows, SearchDirection:=xlPrevious, LookIn:=xlValues).Row
'1st row
lRow = Wkb.Sheets(1).Cells.Find(what:="EQUIPMENT DESCRIPTION", SearchOrder:=xlRows, SearchDirection:=xlPrevious, LookIn:=xlValues).Row + 1
'STHours
Dim i As Integer
For i = lRow To destLRow
Set CopyRng = Wkb.Sheets(1).Range(Cells(i, 5).Address, Cells(i, 11).Address)
Set DestRng = shtDest.Range("O" & shtDest.Cells(Rows.Count, "O").End(xlUp).Row + 1)
CopyRng.Copy
DestRng.PasteSpecial Transpose:=True
Application.CutCopyMode = False 'Clear Clipboard
Set CopyRng = Wkb.Sheets(1).Range(Cells(i, 1).Address, Cells(i, 1).Address)
Set DestRng = shtDest.Range("C" & shtDest.Cells(Rows.Count, "O").End(xlDown).Row)
CopyRng.Copy
DestRng.PasteSpecial Transpose:=True
Application.CutCopyMode = False 'Clear Clipboard
Set CopyRng = Wkb.Sheets(1).Range(Cells(i, 3).Address, Cells(i, 3).Address)
Set DestRng = shtDest.Range("S" & shtDest.Cells(Rows.Count, "O").End(xlUp).Row)
CopyRng.Copy
DestRng.PasteSpecial Transpose:=True
Application.CutCopyMode = False 'Clear Clipboard
i = i + 2
Next i
'Dim cell As Integer
'Dim empname As String
'destLRow = 8 '' find out how to find first available row
'For cell = 2 To lRow
'empname = Wkb.Sheets(1).Cells(cell, 3).Value & " " & Wkb.Sheets(1).Cells(cell, 4).Value
' shtDest.Cells(8, 5).Value = empname
'shtDest.Cells(8, 1).Value = "Service Electric"
'Next cell
' Wkb.Close Save = False
End If
'End If
Filename = Dir()
Loop
MsgBox "Done!"
End Sub
if you want to do in VBA and want to copy one value in "ALL" column
Cells(1,1).Copy Columns(1)

vba code to paste value in open workbooks which have similar name to a range value

I got stuck in the below-mentioned code, what I want to do is to get the value from Range("C4:C" & LastRow) in worksheets X2 that will b changing every time and compare each value with all open workbooks name. If match found then search that value in A column of worksheet X1 and copy all those rows.
The final objective is to paste those rows into those open workbooks which have the same value. For eg: Range C4 has TW00 then the code will search workbooks which have name "TW00.xlsx" and copy all the rows from worksheet X1 which have TW00 value in column A in the worksheet named TW00.xlsx.
Dim BookNames()
ReDim BookNames(Windows.Count)
n = 1
For n = 1 To Windows.Count
BookNames(n) = Workbooks(n).Name
If Workbooks(n).Name = Workbooks("A.xlsx").Worksheets("X2").Range("C4:C" & LastRow).Value Then
Set Rng = Workbooks("A.xlsx").Worksheets("X1").Range("A2:A50000")
For Each c In Rng.Cells
If c.Value = Workbooks("A.xlsx").Worksheets("X2").Range("C4").Value Then
If Not CopyRng Is Nothing Then
Set CopyRng = Application.Union(CopyRng,
Workbooks("A.xlsx").Worksheets("X1").Rows(c))
Else
Set CopyRng = Workbooks("A.xlsx").Worksheets("X1").Rows(c)
End If
End If
Next c
CopyRng.Copy
Workbooks(n).Activate
Worksheets.Add
ActiveSheet.Name = "X1"
ActiveSheet.Paste
End If
Next n
is that code help you?
Sub test()
Dim lastRow As Long
dim sheetName as string
Dim sourceDataSheet As worksheet
Dim sourceSheetsName as worksheet
dim targetDataSheet as worksheet
Dim wkb As Variant
set sourceDataSheet = ActiveWorkbook.Worksheets("X2")
set sourceSheetsName = ActiveWorkbook.Worksheets("X1")
With sourceSheetsName
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
sheetName = .Cells(lastRow, "A")
For Each wkb In Application.Workbooks
If wkb.Name <> .Name And wkb.Name = sheetName Then
set targetDataSheet = wkb.Worksheets.Add
with sourceDataSheet
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
for i = 1 to lastRow
if .Cells(i, "A").Value = sheetName then
.Cells(i, "A").EntireRow.Copy
targetDataSheet.Cells(i, "A").PasteSpecial Paste:=xlPasteValues
end if
next i
end with
End If
Next wkb
End With
End Sub

Excel VBA to summarize last cell of certain column to 'summary' worksheet

I am trying to summarize worksheets (invoices) into "Summary-Sheet" using below code that I found Internet. I am unsuccessfully trying to modify it to select last cell in column F (total amount) which represents total of each invoice.
Total in column F has varying row number based on items sold.
Please help me in updating code to it select total amount from last cell having value in column F.
Thank you!
Sub Summary_All_Worksheets_With_Formulas()
Dim Sh As Worksheet
Dim Newsh As Worksheet
Dim myCell As Range
Dim ColNum As Integer
Dim RwNum As Long
Dim Basebook As Workbook
With Application
.Calculation = xlCalculationManual
.ScreenUpdating = False
End With
'Delete the sheet "Summary-Sheet" if it exist
Application.DisplayAlerts = False
On Error Resume Next
ThisWorkbook.Worksheets("Summary-Sheet").Delete
On Error GoTo 0
Application.DisplayAlerts = True
'Add a worksheet with the name "Summary-Sheet"
Set Basebook = ThisWorkbook
Set Newsh = Basebook.Worksheets.Add
Newsh.Name = "Summary-Sheet"
'The links to the first sheet will start in row 2
RwNum = 1
For Each Sh In Basebook.Worksheets
If Sh.Name <> Newsh.Name And Sh.Visible Then
ColNum = 1
RwNum = RwNum + 1
'Copy the sheet name in the A column
Newsh.Cells(RwNum, 1).Value = Sh.Name
For Each myCell In Sh.Range("A1,A2,C3,E3,C4,E4,C5,E5") '<--Change the range
ColNum = ColNum + 1
Newsh.Cells(RwNum, ColNum).Formula = _
"='" & Sh.Name & "'!" & myCell.Address(False, False)
Next myCell
End If
Next Sh
Newsh.UsedRange.Columns.AutoFit
With Application
.Calculation = xlCalculationAutomatic
.ScreenUpdating = True
End With
End Sub
You do not need to loop through the cells to find your "total amount". I modified part of your code as follows:
If Sh.Name <> Newsh.Name And Sh.Visible Then
ColNum = 1
RwNum = RwNum + 1
'Copy the sheet name in the A column
Newsh.Cells(RwNum, 1).Value = Sh.Name
'put this declaration on top
Dim CellsArray() As String
Dim RangeString As String
Dim intCount As Integer
'your collection of ranges
RangeString = "A1,A2,C3,E3,C4,E4,C5,E5"
'split them into array
CellsArray = Split(RangeString, ",")
'loop through your array
For intCount = LBound(CellsArray) To UBound(CellsArray)
ColNum = ColNum + 1
Newsh.Cells(RwNum, ColNum).Formula = _
"='" & Sh.Name & "'!" & CellsArray(intCount) '<- access each range in array
Next intCount
'Find last row in the column: "Total Amount"
LastRow = Sh.Cells(Sh.Rows.Count, "F").End(xlUp).Row
'Assign that cell to myCell
Set myCell = Sh.Range("F" & LastRow)
'total
ColNum = ColNum + 1
Newsh.Cells(RwNum, ColNum).Formula = _
"='" & Sh.Name & "'!" & myCell.Address(False, False)
End If
Edit: I added the loop cycle in the middle as requested

Data overlaps when merging multiple sheets

I have an Excel workbook which contains n sheets. I want to merge the data from each sheet to one single sheet. The header and data from the first sheet should be on top, the data from second sheet should be below it and so on. All the sheets have the same columns and headers structure. So, the header should appear only once i.e take header and data from first sheet and only data from remaining sheets. I have the following code:
Sub Combine()
'This macro will copy all rows from the first sheet
'(including headers)
'and on the next sheets will copy only the data
'(starting on row 2)
Dim i As Integer
Dim j As Long
Dim SheetCnt As Integer
Dim lstRow1 As Long
Dim lstRow2 As Long
Dim lstCol As Integer
Dim ws1 As Worksheet
With Application
.DisplayAlerts = False
.EnableEvents = False
.ScreenUpdating = False
End With
On Error Resume Next
'Delete the Target Sheet on the document (in case it exists)
Sheets("Target").Delete
'Count the number of sheets on the Workbook
SheetCnt = Worksheets.Count
'Add the Target Sheet
Sheets.Add after:=Worksheets(SheetCnt)
ActiveSheet.Name = "Target"
Set ws1 = Sheets("Target")
lstRow2 = 1
'Define the row where to start copying
'(first sheet will be row 1 to include headers)
j = 1
'Combine the sheets
For i = 1 To SheetCnt
Worksheets(i).Select
'check what is the last column with data
lstCol = ActiveSheet.Cells(1, ActiveSheet.Columns.Count).End(xlToLeft).Column
'check what is the last row with data
lstRow1 = ActiveSheet.Cells(ActiveSheet.Rows.Count, "A").End(xlUp).Row
'Define the range to copy
Range("A2:G2" & j, Cells(lstRow1, lstCol)).Select
'Copy the data
Selection.Copy
ws1.Range("A2:G2" & lstRow2).PasteSpecial
Application.CutCopyMode = False
Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Select
'Define the new last row on the Target sheet
lstRow2 = ws1.Cells(65535, "A").End(xlUp).Row + 1
'Define the row where to start copying
'(2nd sheet onwards will be row 2 to only get data)
j = 3
Next
With Application
.DisplayAlerts = True
.EnableEvents = True
.ScreenUpdating = True
End With
Sheets("Target").Select
Cells.EntireColumn.AutoFit
Range("A1").Select
End Sub
With this code, my data from all sheets is getting overlapped. I want the data to be one below the other.
It's overlapping because you don't increment the paste area on the Target sheet
To fix the problem offset the paste area correspondingly:
Sheet 1: copy 10 rows-paste -> increment paste start & end area by 10
Sheet 2: copy 15 rows-paste -> increment paste start & end area by 25: 10 + 15 and so on...
You can also replace this:
Sheets.Add after:=Worksheets(SheetCnt) 'Add the Target Sheet
ActiveSheet.Name = "Target"
Set ws1 = Sheets("Target")
with this:
Set ws1 = Sheets.Add(after:=Worksheets(SheetCnt)) 'Add the Target Sheet
ws1.Name = "Target"
If you eliminate all "Select" statements and refer to each object explicitly it will allow you to reduce code, and un-needed complexity
Here is my version:
Option Explicit
Public Sub Combine()
Const HEADR As Byte = 1
Dim i As Long, rngCurrent As Range
Dim ws As Worksheet, wsTarget As Worksheet
Dim lCol As Long, lCel As Range
Dim lRow As Long, toLRow As Long
With Application
.DisplayAlerts = False
.EnableEvents = False
.ScreenUpdating = False
End With
For Each ws In Worksheets 'Delete Target Sheet if it exists
With ws
If .Name = "Target" Then
.Delete
Exit For
End If
End With
Next
Set wsTarget = Worksheets.Add(After:=Worksheets(Worksheets.Count))
wsTarget.Name = "Target"
Set lCel = GetMaxCell(Worksheets(1).UsedRange)
If lCel.Row > 1 Then
With Worksheets(1)
'Expected: all sheets will have the same number of columns
lCol = lCel.Column
lRow = HEADR
toLRow = HEADR
.Range(.Cells(HEADR, 1), .Cells(HEADR, lCol)).Copy
With wsTarget
.Range(.Cells(HEADR, 1), .Cells(HEADR, lCol)).PasteSpecial xlPasteAll
End With
End With
For i = 1 To Worksheets.Count 'concatenate data ---------------------------
Set lCel = GetMaxCell(Worksheets(i).UsedRange)
If lCel.Row > 1 Then
With Worksheets(i)
If .Name <> "Target" Then 'exclude the Target
toLRow = toLRow + lRow 'last row on Target
lRow = lCel.Row 'last row on current
Set rngCurrent = .Range(.Cells(HEADR + 1, 1), _
.Cells(lRow, lCol))
lRow = lRow - HEADR
With wsTarget
.Range(.Cells(toLRow, 1), _
.Cells(toLRow + (lRow - HEADR), lCol)) = _
rngCurrent.Value
End With
End If
End With
End If
Next '--------------------------------------------------------------------
With wsTarget
.Columns.AutoFit
.Range("A1").Select
End With
With Application
.CutCopyMode = False
.DisplayAlerts = True
.EnableEvents = True
.ScreenUpdating = True
End With
End If
End Sub
Public Function GetMaxCell(Optional ByRef rng As Range = Nothing) As Range
'Returns the last cell containing a value, or A1 if Worksheet is empty
Const NONEMPTY As String = "*"
Dim lRow As Range, lCol As Range
If rng Is Nothing Then Set rng = Application.ActiveWorkbook.ActiveSheet.UsedRange
If WorksheetFunction.CountA(rng) = 0 Then
Set GetMaxCell = rng.Parent.Cells(1, 1)
Else
With rng
Set lRow = .Cells.Find(What:=NONEMPTY, LookIn:=xlFormulas, _
After:=.Cells(1, 1), _
SearchDirection:=xlPrevious, _
SearchOrder:=xlByRows)
If Not lRow Is Nothing Then
Set lCol = .Cells.Find(What:=NONEMPTY, LookIn:=xlFormulas, _
After:=.Cells(1, 1), _
SearchDirection:=xlPrevious, _
SearchOrder:=xlByColumns)
Set GetMaxCell = .Parent.Cells(lRow.Row, lCol.Column)
End If
End With
End If
End Function
'--------------------------------------------------------------------------------------
Offsetting the paste area is done by incrementing lRow and toLRow
Edit:
If you use this code and you want to transfer cell formatting for all data cells replace this section:
'copy data to Target sheet
With wsTarget
.Range(.Cells(toLRow, 1), .Cells(toLRow + (lRow - HEADR), lCol)) = _
rngCurrent.Value
End With
with this:
'copy data to Target sheet
rngCurrent.Copy
With wsTarget
With .Range(.Cells(toLRow, 1), .Cells(toLRow + (lRow - HEADR), lCol))
.PasteSpecial xlPasteAll
End With
End With
but it will become slower if you're processing a lot of sheets
EDIT: to show how to handle special cases
The above solution is more generic and dynamically detects the last column and row containing data
The number of columns (and rows) to be processed can be manually updated. For example, if your sheets contain 43 columns with data, and you want to exclude the last 2 columns, make the following change to the script:
Line
Set lCel = GetMaxCell(Worksheets(1).UsedRange)
changes to
Set lCel = Worksheets(1).UsedRange("D41")

Compare all columns between two sheets based on a unique identifier column and update Sheet1 rows if difference exists

I have a workbook that has 2 worksheets and sub-sheets Named as per Product Line Column:
NEW DATA sheet
Master Table sheet ("DBQ Query Result")
Subsheets (Driling and Workover, Fishing, Liner Systems, Professional Services, Wellbore Cleaning)
They both have same headers, within the column headers there is a uniqueID column.
PART A
I would like to match uniqueID between those 2 sheets and:
When there is a match, compare row cell values for each column and update if there is difference
When there is a uniqueID in NEW DATA sheet that does not exist in Master Table, I would like this whole row associated to this uniqueId to be copied to Master Table sheet
PART B
I would like to have a new button that when pressed, UniqueID from Master Page will be compared with Unique Id column of each subsheet and:
When there is a match, update subsheet row according to UNIQUEID
When there is no match, that means a new UNIQUEID is created and this should be added to its corresponding subsheet as a last row
I would like to accomplish the above using VBA macro please. I have attached a sample of the excel https://dl.dropboxusercontent.com/u/29585269/Sample.xlsx.
Please let me know if you need any additional information.
I came across few codes online and modified them to fit my need.
So, this is how it goes:
You have 3 Main Sheets next to your PL Sheets - Subsheets (Driling and Workover, Fishing, Liner Systems, Professional Services, Wellbore Cleaning):
Original
Updated
Changes
This code will print the changes between Original Sheet and Updated Sheet:
Option Explicit
Sub CompareSheets()
'
' constants
' worksheets & ranges
' original
Const ksWSOriginal = "ORIGINAL"
Const ksOriginal = "OriginalTable"
Const ksOriginalKey = "OriginalKey"
' updated
Const ksWSUpdated = "UPDATED"
Const ksUpdated = "UpdatedTable"
Const ksUpdatedKey = "UpdatedKey"
' changes
Const ksWSChanges = "CHANGES"
Const ksChanges = "ChangesTable"
' labels
Const ksChange = "CHANGE"
Const ksRemove = "REMOVE"
Const ksAdd = "ADD"
'
' declarations
Dim rngO As Range, rngOK As Range, rngU As Range, rngUK As Range, rngC As Range
Dim c As Range
Dim I As Long, J As Long, lChanges As Long, lRow As Long, bEqual As Boolean
'
' start
Set rngO = Worksheets(ksWSOriginal).Range(ksOriginal)
Set rngOK = Worksheets(ksWSOriginal).Range(ksOriginalKey)
Set rngU = Worksheets(ksWSUpdated).Range(ksUpdated)
Set rngUK = Worksheets(ksWSUpdated).Range(ksUpdatedKey)
Set rngC = Worksheets(ksWSChanges).Range(ksChanges)
With rngC
If .Rows.Count > 1 Then
Range(.Rows(2), .Rows(.Rows.Count)).ClearContents
Range(.Rows(2), .Rows(.Rows.Count)).Font.ColorIndex = xlColorIndexAutomatic
Range(.Rows(2), .Rows(.Rows.Count)).Font.Bold = False
End If
End With
'
' process
lChanges = 1
' 1st pass: updates & deletions
With rngOK
For I = 5 To .Rows.Count
Set c = rngUK.Find(.Cells(I, 1).Value, , xlValues, xlWhole)
If c Is Nothing Then
' deletion
lChanges = lChanges + 1
rngC.Cells(lChanges, 1).Value = ksRemove
For J = 1 To rngO.Columns.Count
rngC.Cells(lChanges, J + 1).Value = rngO.Cells(I, J).Value
rngC.Cells(lChanges, J + 1).Font.Color = vbRed
rngC.Cells(lChanges, J + 1).Font.Bold = True
Next J
Else
bEqual = True
lRow = c.Row - rngUK.Row + 1
For J = 1 To rngO.Columns.Count
If rngO.Cells(I, J).Value <> rngU.Cells(lRow, J).Value Then
bEqual = False
Exit For
End If
Next J
If Not bEqual Then
' change
lChanges = lChanges + 1
rngC.Cells(lChanges, 1).Value = ksChange
For J = 1 To rngO.Columns.Count
If rngO.Cells(I, J).Value = rngU.Cells(lRow, J).Value Then
rngC.Cells(lChanges, J + 1).Value = rngO.Cells(I, J).Value
Else
rngC.Cells(lChanges, J + 1).Value = rngU.Cells(I, J).Value
rngC.Cells(lChanges, J + 1).Font.Color = vbMagenta
rngC.Cells(lChanges, J + 1).Font.Bold = True
End If
Next J
End If
End If
Next I
End With
' 2nd pass: additions
With rngUK
For I = 5 To .Rows.Count
Set c = rngOK.Find(.Cells(I, 1).Value, , xlValues, xlWhole)
If c Is Nothing Then
' addition
lChanges = lChanges + 1
rngC.Cells(lChanges, 1).Value = ksAdd
For J = 1 To rngU.Columns.Count
rngC.Cells(lChanges, J + 1).Value = rngU.Cells(I, J).Value
rngC.Cells(lChanges, J + 1).Font.Color = vbBlue
rngC.Cells(lChanges, J + 1).Font.Bold = True
Next J
End If
Next I
End With
'
' end
Worksheets(ksWSChanges).Activate
rngC.Cells(2, 3).Select
Set rngC = Nothing
Set rngUK = Nothing
Set rngU = Nothing
Set rngOK = Nothing
Set rngO = Nothing
Beep
'
End Sub
This Button Code will Apply Updates to rows noted as "Changes" and "Add" (I dont care about Remove)
Sub Update()
Dim sh1 As Worksheet, sh2 As Worksheet
Dim tempName As String
Dim lastRow1 As Long, lastRow2 As Long
Dim s2Row As Long, s1Row As Long
Application.ScreenUpdating = False
Set sh1 = ActiveWorkbook.Worksheets("ORIGINAL")
Set sh2 = ActiveWorkbook.Worksheets("CHANGES")
lastRow1 = sh1.Cells(Rows.Count, "A").End(xlUp).Row 'Get last row for both sheets
lastRow2 = sh2.Cells(Rows.Count, "A").End(xlUp).Row ' searching both
For s2Row = 2 To lastRow2 'Loop through "CHANGES"
If sh2.Cells(s2Row, 1).Value = "CHANGE" Then
tempName = sh2.Cells(s2Row, 2).Value 'extra step for understanding concept
'There is a match, so now
For s1Row = 2 To lastRow1 'Search through the other sheet
If sh1.Cells(s1Row, 1).Value = tempName Then
For I = 2 To 35
sh1.Cells(s1Row, I).Value = sh2.Cells(s2Row, I + 1).Value 'Copy Values
Next I
End If
Next s1Row
End If
Next s2Row
For s2Row = 2 To lastRow2
If sh2.Cells(s2Row, 1).Value = "ADD" Then
sh2.Range("B" & s2Row & ":BB" & s2Row).Copy 'Copy rows
sh1.Rows(lastRow1 + 1).Insert Shift:=xlDown 'Insert rows
sh1.Cells(lastRow1 + 1, 78).Value = "ADD" 'Classify the row as newly added
End If
Next s2Row
Application.ScreenUpdating = True
Sheets("ORIGINAL").Activate
End Sub
And this button will apply updates to PL Cell Values for existing UniqueIDs changes
Sub Update_PL()
Dim ws As Worksheet
Dim lastRng As Range
Application.ScreenUpdating = False 'speed up code
'Added to loop through all UniqueIDs and update accordingly
Dim sh1 As Worksheet, sh2 As Worksheet
Dim tempName As String
Dim lastRow1 As Long, lastRow2 As Long
Dim s2Row As Long, s1Row As Long
'No Longer requires clearing screen, we will match unique ids and update/add as necessary
'ThisWorkbook.Sheets("ORIGINAL").Rows("5:65536").ClearContents 'clear
Set sh1 = ActiveWorkbook.Worksheets("ORIGINAL") 'Define Master Table
Set sh2 = ws 'Selects Active Sheet
For Each ws In ThisWorkbook.Worksheets
Set lastRng = ThisWorkbook.Sheets("ORIGINAL").Range("A65536").End(xlUp).Offset(1, 0)
Select Case ws.Name
Case "ORIGINAL" 'exlude
Case "UPDATED" 'exlude
Case "CHANGES" 'exlude
Case "Report Table" 'exlude
Case "DASHBOARD" 'exlude
'do nothing
Case Else
ws.Activate
lastRow2 = sh1.Cells(Rows.Count, "A").End(xlUp).Row 'Count Master Table Rows to extract Last Row #
With ActiveSheet
lastRow1 = ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row 'Count Active Sheet Rows to extract Last Row #
End With
For s2Row = 2 To lastRow2 'Loop through Active WorkSheet
tempName = sh1.Cells(s2Row, 1).Value 'Define UniqueID to loop
tempPL = sh1.Cells(s2Row, 22).Value 'Define PL to loop
For s1Row = 2 To lastRow1 'Match UniqueIDs between Master sheet and Active Sheet
If ActiveSheet.Cells(s1Row, 1).Value = tempName Then 'If Matches TRUE then
For I = 2 To 35 'Loop all Columns and update as necessary
ActiveSheet.Cells(s1Row, I).Value = sh1.Cells(s2Row, I).Value 'Copy Values
Next I
End If
Next s1Row
Next s2Row
'copy data from individual sheets
'Range("A2", Range("AB65536").End(xlUp)).Copy lastRng
End Select
Next
Application.CutCopyMode = False 'clear clipboard
Application.ScreenUpdating = True
Sheets("ORIGINAL").Activate
End Sub
And this last button is used to Add new UniqueIDs to corresponding PL
Sub Add_Rows()
Dim ws As Worksheet
Dim lastRng As Range
Application.ScreenUpdating = False 'speed up code
'Added to loop through all UniqueIDs and update accordingly
Dim sh1 As Worksheet
Dim tempPL As String
Dim lastRow1 As Long, lastRow2 As Long
Dim s2Row As Long, s1Row As Long
Set sh1 = ActiveWorkbook.Worksheets("ORIGINAL") 'Define Master Table
For Each ws In ThisWorkbook.Worksheets
Set lastRng = ThisWorkbook.Sheets("ORIGINAL").Range("A65536").End(xlUp).Offset(1, 0)
Select Case ws.Name
Case "ORIGINAL" 'exlude
Case "UPDATED" 'exlude
Case "CHANGES" 'exlude
Case "Report Table" 'exlude
Case "DASHBOARD" 'exlude
'do nothing
Case Else
ws.Activate
lastRow2 = sh1.Cells(Rows.Count, "A").End(xlUp).Row 'Count Master Table Rows to extract Last Row #
With ActiveSheet
lastRow1 = ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row 'Count Active Sheet Rows to extract Last Row #
End With
For s2Row = 5 To lastRow2 'Loop through Active WorkSheet
If sh1.Cells(s2Row, 78).Value = "ADD" Then
tempPL = sh1.Cells(s2Row, 23).Value
If ActiveSheet.Name = tempPL Then
sh1.Range("A" & s2Row & ":AB" & s2Row).Copy 'Copy rows
ActiveSheet.Rows(lastRow1 + 1).Insert Shift:=xlDown 'Insert rows
sh1.Cells(s2Row, 78).Value = "ADDED" 'Validate Row has been added in Master Sheet
End If
End If
Next s2Row
End Select
Next
Application.CutCopyMode = False 'clear clipboard
Application.ScreenUpdating = True 'Resume ScreenUpdating
Sheets("ORIGINAL").Activate 'Display Original Sheet
End Sub
Complicated? Yeah... but solved my issue.
BR! Eddy