I currently have a macro that merges all the tabs except for a tab named "Combined". This combined sheet will be the destination of the merging of all tabs/sheets. However, I want to exclude some of the tabs from being combined.
For example, I have 5 tabs: Combined, tab1, tabA, tab2, tabB. All tabs have similar number of columns/column headers. When I run the macro it will merge tab1, tabA, tab2, and tabB into Combined. What I want to revise with my current macro is to only combine tab1 and tabA. How will I need to change my current macro?
Here is my current macro:
Option Explicit
Public Sub CombineDataFromAllSheets()
Sheets("Combined").Rows("2:" & Sheets("Combined").Rows.Count).ClearContents
Dim wksSrc As Worksheet, wksDst As Worksheet
Dim rngSrc As Range, rngDst As Range
Dim lngLastCol As Long, lngSrcLastRow As Long, lngDstLastRow As Long
'Notes: "Src" is short for "Source", "Dst" is short for "Destination"
'Set references up-front
Set wksDst = ThisWorkbook.Worksheets("Combined")
lngDstLastRow = LastOccupiedRowNum(wksDst) '<~ defined below (and in Toolbelt)!
lngLastCol = LastOccupiedColNum(wksDst) '<~ defined below (and in Toolbelt)!
'Set the initial destination range
Set rngDst = wksDst.Cells(lngDstLastRow + 1, 1)
'Loop through all sheets
For Each wksSrc In ThisWorkbook.Worksheets
'Make sure we skip the "Import" destination sheet!
If wksSrc.Name <> "Combined" Then
'Identify the last occupied row on this sheet
lngSrcLastRow = LastOccupiedRowNum(wksSrc)
'Store the source data then copy it to the destination range
With wksSrc
Set rngSrc = .Range(.Cells(2, 1), .Cells(lngSrcLastRow, lngLastCol))
rngSrc.Copy Destination:=rngDst
End With
'Redefine the destination range now that new data has been added
lngDstLastRow = LastOccupiedRowNum(wksDst)
Set rngDst = wksDst.Cells(lngDstLastRow + 1, 1)
End If
Next wksSrc
End Sub
Define an array with the sheet names and then iterate this array
Dim arrSheets(1) as String
arrSheets(0) = "tab1"
arrSheets(1) = "tabA"
Dim i as long
For i = 0 to Ubound(arrSheets)
Set wksSrc = Thisworkbook.worksheets(arrSheets(i))
....
next
BTW 1: Avoid implicit referencing of sheets and ranges - always use explicit referencing, like thisworkbook.worksheets or wksSrc.range(...)
BTW 2: You don't need copy/paste - just write the values to the target:
With rngSrc
rngDst.Resize(.Rows.Count, .Columns.Count).Value = .Value 'this is much faster and you don't need the clipboard
End With
#Ike offered a great answer. Theirs and mine are two variations on the same idea: Create a list of sheets to work on, and then loop through that instead of through all sheets in the workbook.
I also cleaned up some other parts to better implement this new idea. Here is the revised code:
Option Explicit
Public Sub CombineDataFromAllSheets()
Dim wksSrc As Variant, wksDst As Worksheet
Dim rngSrc As Range, rngDst As Range
Dim lngLastCol As Long, lngSrcLastRow As Long, lngDstLastRow As Long
Dim SourceSheets As Variant
'Notes: "Src" is short for "Source", "Dst" is short for "Destination"
'Set references up-front
Set wksDst = ThisWorkbook.Worksheets("Combined")
lngDstLastRow = LastOccupiedRowNum(wksDst) '<~ defined below (and in Toolbelt)!
lngLastCol = LastOccupiedColNum(wksDst) '<~ defined below (and in Toolbelt)!
'List of sheets to operate on
SourceSheets = Array( _
ThisWorkbook.Worksheets("tab1"), _
ThisWorkbook.Worksheets("tabA") _
)
wksDst.Rows("2:" & Sheets("Combined").Rows.Count).ClearContents
'Set the initial destination range
Set rngDst = wksDst.Cells(lngDstLastRow + 1, 1)
'Loop through all sheets
For Each wksSrc In SourceSheets
'Identify the last occupied row on this sheet
lngSrcLastRow = LastOccupiedRowNum(wksSrc)
'Store the source data then copy it to the destination range
With wksSrc
Set rngSrc = .Range(.Cells(2, 1), .Cells(lngSrcLastRow, lngLastCol))
rngSrc.Copy Destination:=rngDst
End With
'Redefine the destination range now that new data has been added
lngDstLastRow = LastOccupiedRowNum(wksDst)
Set rngDst = wksDst.Cells(lngDstLastRow + 1, 1)
Next wksSrc
End Sub
Related
I am trying to repurpose combine_data_from_all_sheets.vb to pull data from several tabs.
Starting at O7:T7.
The data starts in the same range for each tab.
Some tabs may not have data and can be skipped.
These tabs have formulas with double quotes instead.
If there is data there won't be any blank spaces.
If row 11 has data then so does 7, 8, 9 and 10
The areas that I'm having trouble with I wrote notes within the code, which is all of the text in full caps.
Option Explicit
Public Sub CombineDataFromAllSheets()
Dim wksSrc As Worksheet, wksDst As Worksheet
Dim rngSrc As Range, rngDst As Range
Dim lngLastCol As Long, lngSrcLastRow As Long, lngDstLastRow As Long
'Notes: "Src" is short for "Source", "Dst" is short for "Destination"
'Set references up-front
Set wksDst = ThisWorkbook.Worksheets("AOD")
lngDstLastRow = LastOccupiedRowNum(wksDst) '<- defined below
lngLastCol = LastOccupiedColNum(wksDst) '<- defined below
'Set the initial destination range
Set rngDst = wksDst.Cells(lngDstLastRow + 1, 1)
'Loop through all sheets
For Each wksSrc In ThisWorkbook.Worksheets
'Skip template sheet
'WOULD LIKE TO ADD AN OR STATEMENT HERE, SOMETHING LIKE NAME <> "TEMPLATE" OR "LIST" THEN
If wksSrc.Name <> "Template" Then
'WOULD LIKE THIS TO SEARCH FOR LAST ROW WITH DATA THAT ISN'T DOUBLE QUOTES/A FORMULA WITH NO VISIBLE VALUES
'Identify the last occupied row on this sheet
lngSrcLastRow = LastOccupiedRowNum(wksSrc)
'Store the source data then copy it to the destination range
'WOULD LIKE TO ONLY COPY DATA IF THERE ARE VALUES IN CELLS, BUT MACRO IS PICKING UP CELLS WITH DOUBLE QUOTES
'WOULD LIKE FOR THE MACRO TO ONLY COPY IF DATA EXISTS IN RANGE "O7:T7", IF DATA EXISTS HERE, CONTINUE TO COPY ALL DATA BELOW UNTIL CELLS ARE EMPTY (SKIP CELLS WITH "" AS VALUES)
'WOULD LIKE TO COPY AND PASTE SPECIAL INSTEAD OF FORMULAS
With wksSrc
Set rngSrc = .Range("O7:T7")
rngSrc.Copy Destination:=rngDst
End With
'Redefine the destination range now that new data has been added
lngDstLastRow = LastOccupiedRowNum(wksDst)
Set rngDst = wksDst.Cells(lngDstLastRow + 1, 1)
End If
Next wksSrc
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'INPUT : Sheet, the worksheet we'll search to find the last row
'OUTPUT : Long, the last occupied row
'SPECIAL CASE: if Sheet is empty, return 1
Public Function LastOccupiedRowNum(Sheet As Worksheet) As Long
Dim lng As Long
If Application.WorksheetFunction.CountA(Sheet.Cells) <> 0 Then
With Sheet
lng = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
End With
Else
lng = 1
End If
LastOccupiedRowNum = lng
End Function
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'INPUT : Sheet, the worksheet we'll search to find the last column
'OUTPUT : Long, the last occupied column
'SPECIAL CASE: if Sheet is empty, return 1
Public Function LastOccupiedColNum(Sheet As Worksheet) As Long
Dim lng As Long
If Application.WorksheetFunction.CountA(Sheet.Cells) <> 0 Then
With Sheet
lng = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
End With
Else
lng = 1
End If
LastOccupiedColNum = lng
End Function
Copy Data From Multiple Worksheets
Option Explicit
Sub CombineDataWorksheets()
' Define constants.
' Source
Const sFirstRowAddress As String = "O7:T7"
' The following two constants are related!
Const sNameExceptionsList As String = "AOD,Template,List"
Const sNameExceptionsDelimiter As String = ","
' Destination
Const dName As String = "AOD"
Const dFirstColumn As String = "A"
' Reference the workbook ('wb').
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Reference the destination worksheet ('dws').
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
' Write the number of worksheet rows to a variable ('wsrCount').
Dim wsrCount As Long: wsrCount = dws.Rows.Count
' Using the destination worksheet with the source first row address,
' write the following three source properties to variables.
Dim cCount As Long ' Source/Destination Columns Count
Dim sfRow As Long ' Source First Row
Dim scrgAddress As String ' Source Columns Range Address
With dws.Range(sFirstRowAddress)
cCount = .Columns.Count
sfRow = .Row
scrgAddress = .Resize(wsrCount - sfRow + 1).Address
End With
' Reference the destination first row range.
Dim dfrrg As Range ' Destination First Row Range
' Attempt to reference the last destination worksheet's row,
' the row of the bottom-most NON-EMPTY cell.
' Note that the Find method with its LookIn argument's parameter
' set to 'xlFormulas' will fail if the worksheet is filtered.
' It will NOT fail if rows or columns are just hidden.
Dim dlCell As Range
Set dlCell = dws.UsedRange.Find("*", , xlFormulas, , xlByRows, xlPrevious)
If dlCell Is Nothing Then ' the destination worksheet is empty
Set dfrrg = dws.Cells(1, dFirstColumn).Resize(, cCount)
Else ' the destination worksheet is not empty
Set dfrrg = dws.Cells(dlCell.Row + 1, dFirstColumn).Resize(, cCount)
End If
' Write the names from the name exception list to a zero-based string array,
' the name exceptions array ('sNameExceptions').
Dim sNameExceptions() As String
sNameExceptions = Split(sNameExceptionsList, sNameExceptionsDelimiter)
' Declare additional variables to be used in the loop.
Dim sws As Worksheet ' Source Worksheet
Dim srg As Range ' Source Range
Dim slCell As Range ' Source Last Cell
Dim rCount As Long ' Source/Destination Rows Count
Dim drg As Range ' Destination Range
' Loop through the worksheets collection of the workbook...
For Each sws In wb.Worksheets
' Check if the source name was NOT found in the name exceptions array.
If IsError(Application.Match(sws.Name, sNameExceptions, 0)) Then
' Reference the source columns range, the range from the first
' source row range to the bottom-most worksheet row range.
With sws.Range(scrgAddress)
' Attempt to reference the source worksheet's last row,
' the row of the bottom-most NON-BLANK cell.
' Note that the Find method with its LookIn argument's
' parameter set to 'xlValues' will fail if the worksheet
' is filtered, and even if rows or columns are just hidden.
Set slCell = .Find("*", , xlValues, , xlByRows, xlPrevious)
' Check if a source non-blank cell was found.
If Not slCell Is Nothing Then ' non-blank cell found
' Calculate the number of source/destination rows.
rCount = slCell.Row - sfRow + 1
' Reference the source range.
Set srg = .Resize(rCount)
' Reference the destination range.
Set drg = dfrrg.Resize(rCount)
' Write the values from the source to the destination range.
drg.Value = srg.Value
' Reference the next destination first row range.
Set dfrrg = dfrrg.Offset(rCount)
'Else ' non-blank cell not found; do nothing
End If
End With
'Else ' worksheet name is in the name exceptions array; do nothing
End If
Next sws
' Inform.
MsgBox "Data combined.", vbInformation
End Sub
Okay,
Option Explicit
Sub Pull_All_To_AOD()
Dim wksSrc As Worksheet 'Source Sheet
Dim wksDst As Worksheet 'Destination Sheet
Dim rngSrc As Range 'Source Range
Dim rngDst As Range 'Destination Range
Dim RowCount As Long
Set wksDst = ThisWorkbook.Worksheets("AOD")
'Iterate Worksheets
For Each wksSrc In ThisWorkbook.Worksheets
'Skip Template, AOD, and empty sheets
If wksSrc.Name <> "Template" And _
wksSrc.Name <> "AOD" And _
Trim(Application.WorksheetFunction.Concat(wksSrc.Range("O7:T7"))) <> "" Then
'Find Data Size
RowCount = wksSrc.Range("O" & Rows.Count).End(xlUp).Row - 6
'Copy Data to AOD sheet, next empty row
wksDst.Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Resize(RowCount, 6).Value = _
wksSrc.Range("O7").Resize(RowCount, 6).Value
End If
Next wksSrc
End Sub
I think this is what you're looking for. Let me know if I'm missing anything.
I am trying to copy data from cells F11:Z22 on multiple sheets and output the data onto one summary sheet.
Sample of Data to Copy
There is the possibility to have new sheets added. I would like to get data from those sheets as well.
I have Sheets "SummarySheet", "Import", "TemplateSheet" I do not want to copy data from. The other sheets I do.
The ideal output would be just all of the values listed out in the "Import" sheet.
Example of Result
I tried a few different macros. This one logically works the best. When I execute it, nothing happens.
Sub SummarizeSKUdata()
Dim wksSrc As Worksheet, wksDst As Worksheet
Dim rngSrc As Range, rngDst As Range
Dim lngLastCol As Long, lngSrcLastRow As Long, lngDstLastRow As Long
'Notes: "Src" is short for Source, "Dst" is short for Destination
'Set Referances up-front
Set wksDst = ThisWorkbook.Worksheets("Import")
lngDstLastRow = wksDst.Cells.SpecialCells(xlCellTypeLastCell).Row '<-defined below
lngLastCol = wksDst.UsedRange.Columns(wksDst.UsedRange.Columns.Count).Column '<-defined below
'set the initial destination range
Set rngDst = wksDst.Cells(lngDstLastRow + 1, 1)
'Loop Through all sheets
For Each wksSrc In ThisWorkbook.Worksheets
'Make Sure we skip the Summary Sheet
If wksSrc.Name <> "SummarySheet" Then
If wksSrc.Name <> "Import" Then
If wksSrc.Name <> "TemplateSheet" Then
'Identify the last row occupied on this sheet
lngSrcLastRow = wksDst.Cells.SpecialCells(xlCellTypeLastCell).Row
'Store the source data then copy it to the destination range
With wksSrc
Set rngSrc = Range("F11:Z22")
rngSrc.Copy Destination:=rngDst
End With
'Redefine the destination range now that new data has been added
lngDstLastRow = wksDst.Cells.SpecialCells(xlCellTypeLastCell).Row
Set rngDst = wksDst.Cells(lngDstLastRow + 1, 1)
End If
End If
End If
Next wksSrc
End Sub
I was able to figure it out with this code below.
Sub SummarizeSKUdata()
Dim wksSrc As Worksheet, wksDst As Worksheet
Dim rngSrc As Range, rngDst As Range
Dim lngLastCol As Long, lngSrcLastRow As Long, lngDstLastRow As Long
'Notes: "Src" is short for Source, "Dst" is short for Destination
'Set Referances up-front
Set wksDst = ThisWorkbook.Worksheets("Import")
wksDst.Rows("2:" & Rows.Count).ClearContents
'set the initial destination range
Set rngDst = wksDst.Cells(lngDstLastRow + 2, 1)
'Loop Through all sheets
For Each wksSrc In ThisWorkbook.Worksheets
lngDstLastRow = wksDst.Cells.SpecialCells(xlCellTypeLastCell).Row '<-defined below
lngLastCol = wksDst.UsedRange.Columns(wksSrc.UsedRange.Columns.Count).Column '<-defined below
'Make Sure we skip the Summary Sheet
If wksSrc.Name <> "SummarySheet" Then
If wksSrc.Name <> "Import" Then
If wksSrc.Name <> "TemplateSheet" Then
'Identify the last row occupied on this sheet
lngSrcLastRow = wksDst.Cells.SpecialCells(xlCellTypeLastCell).Row
'Store the source data then copy it to the destination range
With wksSrc
wksSrc.Range("F11:Z22").Copy
rngDst.PasteSpecial Paste:=xlPasteValues
End With
'Redefine the destination range now that new data has been added
lngDstLastRow = wksDst.Cells.SpecialCells(xlCellTypeLastCell).Row
Set rngDst = wksDst.Cells(lngDstLastRow + 1, 1)
End If
End If
End If
Next wksSrc
End Sub
I have a problem with VBA code not pasting values
The code goes as following
Set rngSrc = .Range("D29")
rngSrc.Copy Destination:=rngDst
The problem is that I get only #REF errors since the VBA tries to paste whatever the cell has but I would like it to paste special values and I cant make it work with paste special function.
Does someone know how to make it work?
You're almost there, but instead of the Destination method, you should be using PasteSpecial instead, check this nifty code below:
Private Sub copypaste()
Dim rngSrc As Range
Dim rngDest As Range
Dim ws As Worksheet: Set ws = Sheets("Your sheet name")
Set rngSrc = ws.Range("D29")
Set rngDest = ws.Range("A33") ' for example
rngSrc.Copy
rngDest.PasteSpecial xlPasteValues
End Sub
I feel like the code is pretty self-explanatory. Though if you have any questions, let me know
Your CombineDataFromAllSheets code should be:
Public Sub CombineDataFromAllSheets()
Dim wksSrc As Worksheet, wksDst As Worksheet
Dim rngSrc As Range, rngDst As Range
Dim lngLastCol As Long, lngSrcLastRow As Long, lngDstLastRow As Long
Set wksDst = ThisWorkbook.Worksheets("Import")
For Each wksSrc In ThisWorkbook.Worksheets
'These need updating on each pass of the loop.
'Set them at the start, rather than before the loop
'and at the end of the loop.
lngDstLastRow = LastOccupiedRowNum(wksDst)
lngLastCol = LastOccupiedColNum(wksDst)
Set rngDst = wksDst.Cells(lngDstLastRow + 1, 1)
If wksSrc.Name <> "Import" Then
lngSrcLastRow = LastOccupiedRowNum(wksSrc)
With wksSrc
Set rngSrc = .Range("D29")
rngSrc.Copy
rngDst.PasteSpecial xlPasteValues
End With
End If
Next wksSrc
End Sub
How to add a counter for every new sheet combine?
Red is the 1st sheet combine
Yellow is the 2nd sheet combine
Green is the 3rd sheet combine
No need to add color .... however i been trying to add a counter in but i do not know how to do it ... and place it above each data imported
it might be my way of using the macro wrongly ...
hope someone helps me out ....
image
Sub GetSheets()'Update Excel Junction.com
Path = "C:\Users\momo\Desktop\Miscellaneous Shipment Packing List\New folder\"
Filename = Dir(Path & "*.xls")
Do While Filename <> ""
Workbooks.Open Filename:=Path & Filename, ReadOnly:=True
For Each Sheet In ActiveWorkbook.Sheets
Sheet.Copy After:=ThisWorkbook.Sheets(1)
Next Sheet
Workbooks(Filename).Close
Filename = Dir()
Loop
End Sub
Sub CombineDataFromAllSheets()
Dim wksSrc As Worksheet, wksDst As Worksheet
Dim rngSrc As Range, rngDst As Range
Dim lngLastCol As Long, lngSrcLastRow As Long, lngDstLastRow As Long
'Notes: "Src" is short for "Source", "Dst" is short for "Destination"
'Set references up-front
Set wksDst = ThisWorkbook.Worksheets("Combine")
lngDstLastRow = LastOccupiedRowNum(wksDst) '<~ defined below (and in Toolbelt)!
lngLastCol = LastOccupiedColNum(wksDst) '<~ defined below (and in Toolbelt)!
'Set the initial destination range
Set rngDst = wksDst.Cells(lngDstLastRow + 1, 2)
'Loop through all sheets
For Each wksSrc In ThisWorkbook.Worksheets
'Make sure we skip the "Import" destination sheet!
If wksSrc.Name <> "Combine" Then
'Identify the last occupied row on this sheet
lngSrcLastRow = LastOccupiedRowNum(wksSrc)
'Store the source data then copy it to the destination range
With wksSrc
Set rngSrc = .Range(.Cells(2, 6), .Cells(lngSrcLastRow, lngLastCol))
rngSrc.Copy Destination:=rngDst
End With
'Redefine the destination range now that new data has been added
lngDstLastRow = LastOccupiedRowNum(wksDst)
Set rngDst = wksDst.Cells(lngDstLastRow + 2, 1)
End If
Next wksSrc
End Sub
'''''''''''''''''
'INPUT : Sheet, the worksheet we'll search to find the last row
'OUTPUT : Long, the last occupied row
'SPECIAL CASE: if Sheet is empty, return 1
Public Function LastOccupiedRowNum(Sheet As Worksheet) As Long
Dim lng As Long
If Application.WorksheetFunction.CountA(Sheet.Cells) <> 0 Then
With Sheet
lng = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
End With
Else
lng = 1
End If
LastOccupiedRowNum = lng
End Function
''''''''''''''''''''''''''''''''
'INPUT : Sheet, the worksheet we'll search to find the last column
'OUTPUT : Long, the last occupied column
'SPECIAL CASE: if Sheet is empty, return 1
Public Function LastOccupiedColNum(Sheet As Worksheet) As Long
Dim lng As Long
If Application.WorksheetFunction.CountA(Sheet.Cells) <> 0 Then
With Sheet
lng = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
End With
Else
lng = 1
End If
LastOccupiedColNum = lng
End Function
The simplest approach is to add a static counter, but this will be reset each time you open the workbook. The more resilient approach will be to find the last counter and add one.
I am not able to create fully tested code here, but the following should give enough of an idea. Remember that proper indenting and Option Explicit are your friends. Also, I have not put any other optimisations in your code - e.g. check how many times you really need to set your destination range and where it is best to set it.
Sub CombineDataFromAllSheets()
Dim importCounter as Long '**** Added this
Dim wksSrc As Worksheet, wksDst As Worksheet
Dim rngSrc As Range, rngDst As Range
Dim lngLastCol As Long, lngSrcLastRow As Long, lngDstLastRow As Long
'Notes: "Src" is short for "Source", "Dst" is short for "Destination"
'Set references up-front
Set wksDst = ThisWorkbook.Worksheets("Combine")
lngDstLastRow = LastOccupiedRowNum(wksDst) '<~ defined below (and in Toolbelt)!
lngLastCol = LastOccupiedColNum(wksDst) '<~ defined below (and in Toolbelt)!
'Set the initial destination range
Set rngDst = wksDst.Cells(lngDstLastRow + 1, 2)
'**** Find and set the Counter - not tested for error conditions (what if the sheet is empty?)
importCounter = wksDst.Cells(Range("A" & lngDstLastRow).End(xlUp).Row,1)
'Loop through all sheets
For Each wksSrc In ThisWorkbook.Worksheets
'Make sure we skip the "Import" destination sheet!
If wksSrc.Name <> "Combine" Then
'Identify the last occupied row on this sheet
lngSrcLastRow = LastOccupiedRowNum(wksSrc)
'Store the source data then copy it to the destination range
With wksSrc
'**** increment and insert the counter
'**** in order to do this, had to fix rngDst, set it where it is used rather then too early.
Set rngDst = wksDst.Cells(lngDstLastRow + 1, 1)
importCounter = importCounter + 1
rngDst = importCounter
lngDstLastRow = lngDstLastRow + 1
Set rngDst = wksDst.Cells(lngDstLastRow + 1, 2)
Set rngSrc = .Range(.Cells(2, 6), .Cells(lngSrcLastRow, lngLastCol))
rngSrc.Copy Destination:=rngDst
End With
'Redefine the destination range now that new data has been added
lngDstLastRow = LastOccupiedRowNum(wksDst)
Set rngDst = wksDst.Cells(lngDstLastRow + 2, 1)
End If
Next wksSrc
End Sub
Would like to create a Macro to loop through all of the sheets in the workbook and select all the data from each worksheet and then paste said data into a single consolidate table on the "Master" sheet. All sheets have the same column heading to Column "AB".
Currently tried using this code but I have been unable to get anything to paste over onto the Master worksheet. Might be overthinking setting the range each tab.
Just looking for a simple solution to copy all active data from each sheet and paste it into one sheet so that is its all consolidated.
Thanks in advance!
Sub CombineData()
Dim wkstDst As Worksheet
Dim wkstSrc As Worksheet
Dim WB As Workbook
Dim rngDst As Range
Dim rngSrc As Range
Dim DstLastRow As Long
Dim SrcLastRow As Long
'Refrences
Set wkstDst = ActiveWorkbook.Worksheets("Master")
'Setting Destination Range
Set rngDst = wkstDst.Cells(DstLastRow + 1, 1)
'Loop through all sheets exclude Master
For Each wkstSrc In ThisWorkbook.Worksheets
If wkstSrc.Name <> "Master" Then
SrcLastRow = LastOccupiedRowNum(wkstSrc)
With wkstSrc
Set rngSrc = .Range(.Cells(2, 1), .Cells(SrcLastRow, 28))
rngSrc.Copy Destination:=rngDst
End With
DstLastRow = LastOccupiedRowNum(wkstDst)
Set rngDst = wkstDst.Cells(DstLastRow + 1, 1)
End If
Next wkstSrc
End Sub
Throwing another method into the mix. This does assume that the data you are copying has as many rows in column A as it does in any other column. It doesn't require your function.
Sub CombineData()
Dim wkstDst As Worksheet
Dim wkstSrc As Worksheet
Dim rngSrc As Range
Set wkstDst = ThisWorkbook.Worksheets("Master")
For Each wkstSrc In ThisWorkbook.Worksheets
If wkstSrc.Name <> "Master" Then
With wkstSrc
Set rngSrc = .Range(.Cells(2, 1), .Cells(.Rows.Count, 1).End(xlUp)).Resize(, 28)
rngSrc.Copy Destination:=wkstDst.Cells(Rows.Count, 1).End(xlUp)(2)
End With
End If
Next wkstSrc
End Sub
You have copied this from somewhere else and you have forgotten to copy the function that gets the last row of a worksheet, namely this one LastOccupiedRowNum
So add this function to the same module and the code should work. Please don't forget to mark this as the right answer if it did work:
Function LastOccupiedRowNum(Optional sh As Worksheet, Optional colNumber As Long = 1) As Long
'Finds the last row in a particular column which has a value in it
If sh Is Nothing Then
Set sh = ActiveSheet
End If
LastOccupiedRowNum= sh.Cells(sh.Rows.Count, colNumber).End(xlUp).row
End Function
Try finding the last row dynamically, rather than using .cells
Dim lrSrc as Long, lrDst as Long, i as Long
For i = 1 to Sheets.Count
If Not Sheets(i).Name = "Destination" Then
lrSrc = Sheets(i).Cells( Sheets(i).Rows.Count,"A").End(xlUp).Row
lrDst = Sheets("Destination").Cells( Sheets("Destination").Rows.Count, "A").End(xlUp).Row
With Sheets(i)
.Range(.Cells(2,"A"), .Cells(lrSrc,"AB")).Copy Sheets("Destination").Range(Sheets("Destination").Cells(lrDst+1,"A"),Sheets("Destination").Cells(lrDst+1+lrSrc,"AB"))
End With
End If
Next i
This should replace your sub and the related function.