consolidate multiple worksheets into one worksheet - excel

I want to consolidate multiple worksheets into one worksheet in the same excel, but i don't want some data after a specific word "Total" in all the worksheets. What should i do to delete the data after the word "Total" and then consolidate all the sheets.
Below code is written to add multiple worksheets.
Sub Consolidate()
Dim sh As Worksheet
Dim DestSh As Worksheet
Dim erow As Long, lrowsh As Long, startrow As Long
Dim CopyRng As Range
startrow = 3
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'Deleting "Consolidate" sheet
Application.DisplayAlerts = False
On Error Resume Next
ActiveWorkbook.Worksheets("Consolidate").Delete
On Error GoTo 0
Application.DisplayAlerts = True
'Adding worksheet with the name "Consolidate"
Set DestSh = ActiveWorkbook.Worksheets.Add
DestSh.Name = "Consolidate"
'loop through all worksheets and copy the data to the DestSh
For Each sh In ActiveWorkbook.Worksheets
If sh.Name <> DestSh.Name Then
'Find the next blank or empty row on the DestSh
erow = DestSh.Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Row
'Find the last row with data in the Sheet
lrowsh = sh.Range("A" & Rows.Count).End(xlUp).Row
Set CopyRng = sh.Range(sh.Rows(startrow), sh.Rows(lrowsh))
'copies Values / formats
CopyRng.Copy
With DestSh.Cells(erow, 1)
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
End With
End If
Next
End Sub

Interesting Workbook Consolidation
Change the constants (Const) to fit your needs.
The Code
Sub Consolidate()
' Target
Const cTarget As String = "Consolidate" ' Target Worksheet Name
' Source
Const cFR As Long = 3 ' First Row Number
Const cLRC As Variant = 1 ' Last-Row Column Letter/Column Number
Const cCrit As String = "Total" ' Criteria
Dim wb As Workbook ' Target Workbook
Dim wsT As Worksheet ' Target Worksheet
Dim ws As Worksheet ' Current Source Worksheet
Dim eRow As Long ' Target First Empty Row
Dim lRow As Long ' Source Last Used Row
Dim lCol As Long ' Source Last Used Column
Dim rngCell As Range ' Cell Ranges
Dim rng As Range ' Ranges
' Speed up.
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
' Create a reference to Target Workbook. If the code will NOT be in the
' workbook to be processed, then use its name (preferable) or
' ActiveWorkbook instead of ThisWorkbook.
Set wb = ThisWorkbook
' Note: Instead of the following with block you could use code to clear
' or clear the contents of the Target Worksheet.
With wb
'Delete Target Worksheet.
Application.DisplayAlerts = False
On Error Resume Next
.Worksheets("Consolidate").Delete
On Error GoTo 0
Application.DisplayAlerts = True
'Add Target Worksheet.
Set wsT = .Worksheets.Add(Before:=.Sheets(1)) ' First Tab
wsT.Name = "Consolidate"
End With
' Handle errors.
On Error GoTo ErrorHandler
' Loop through all worksheets.
For Each ws In wb.Worksheets
If ws.Name <> wsT.Name Then
With ws.Cells(cFR, cLRC).Resize(ws.Rows.Count - cFR + 1, _
ws.Columns.Count - cLRC + 1)
' Note: Choose only one of the following two lines.
'Find the first occurrence of Criteria in Current Worksheet.
Set rngCell = .Find(cCrit, .Cells(.Rows.Count, .Columns _
.Count), xlValues, xlWhole, xlByRows, xlNext)
' 'Find the last occurrence of Criteria in Current Worksheet.
' Set rng = .Find(cCrit, , xlValues, xlWhole, xlByRows, _
' xlPrevious)
' Clear the range below the row where Criteria was found.
ws.Rows(rngCell.Row + 1 & ":" & ws.Rows.Count).Clear
' Create a reference to Row Range (of Copy Range).
Set rng = .Cells(1).Resize(rngCell.Row - cFR + 1, _
.Columns.Count - cLRC + 1)
End With
' Create a reference to last cell in last column of Row
' Range (of Copy Range).
Set rngCell = rng.Find("*", , xlFormulas, , _
xlByColumns, xlPrevious)
' Create a reference to Copy Range.
Set rng = rng.Cells(1).Resize(rng.Rows.Count, _
rngCell.Column - cLRC + 1)
'Find the next blank or empty row in Target Worksheet.
eRow = wsT.Cells(wsT.Rows.Count, cLRC).End(xlUp) _
.Offset(1, 0).Row
' Copy Copy Range.
rng.Copy
' In (First Empty Row of) Target Worksheet
With wsT.Cells(eRow, 1)
' First paste the formats to avoid trouble mostly when pasting
' dates or time. Excel might firstly format it differently, and
' when pasting the formats might not revert to desired formats.
.PasteSpecial xlPasteFormats
.PasteSpecial xlPasteValues
Application.CutCopyMode = False
End With
End If
Next
' Go to the top of Target Worksheet.
ActiveSheet.Range("A1").Select
' Inform user of success (Since the code is fast, you might not know if it
' had run at all).
MsgBox "The operation finished successfully.", vbInformation, "Success"
ProcedureExit:
' Speed down.
With Application
.Calculation = xlCalculationAutomatic
.ScreenUpdating = True
End With
Exit Sub
ErrorHandler:
MsgBox "An unexpected error occurred. Error '" & Err.Number & "': " _
& Err.Description, vbCritical, "Error"
GoTo ProcedureExit
End Sub

Related

searching for data in a lot of sheets and copying entire row if data is found to a separate work sheet in VBA

Hi I'm relatively new to VBA and programing and im having an "overflow" issue with my code
I'm trying to to go through the first 31 work sheets search for the term "Power On" in column C and when it find a match copy the entire row and paste it into Sheet33 it was working at one point for just a single sheet but now i cant get it to work after modifying it for the first 31 sheets
any help would be greatly appreciated!
Sub test()
Dim LSearchRow As Integer
Dim LCopyToRow As Integer
Dim ws1 As Worksheet
Dim I As Integer
LCopyToRow = 1
For I = 1 To 31
Set ws1 = ActiveSheet
LSearchRow = 1
While Len(Range("A" & CStr(LSearchRow)).Value) > 0
'If value in column C = "Power On", copy entire row to Sheet33
If Range("C" & CStr(LSearchRow)).Value = "Power On" Then
'Select row in ws1 to copy
Rows(CStr(LSearchRow) & ":" & CStr(LSearchRow)).Select
Selection.Copy
'Paste row into Sheet33 in next row
Sheets("Sheet33").Select
Rows(CStr(LCopyToRow) & ":" & CStr(LCopyToRow)).Select
ActiveSheet.Paste
LCopyToRow = LCopyToRow + 1
'Go back to ws1
Sheets(ws1).Select
End If
LSearchRow = LSearchRow + 1
Wend
Exit Sub
Next I
End Sub
'Overflow' error happens when your declared data variable of a certain datatype can no longer hold the SIZE of the value you are putting in it.
Based on your code, LSearchRow and LCopyToRow are declared as INTEGER which can hold up to 32767 (rows). to fix this declare it as LONG instead of INTEGER:
Dim LSearchRow As Long
Dim LCopyToRow As Long
Here's an update to my answer. I made an alternative version of your code:
Sub GetPowerOn()
Dim ws As Worksheet
Dim wsResult As Worksheet
Dim nrow As Long
Dim actvCell As Range
Dim actvLrow As Long
Set wsResult = ThisWorkbook.Worksheets("Sheet33")
Application.ScreenUpdating = False
For Each ws In ThisWorkbook.Worksheets '~Loop through the sheets of the workbook
If Not ws.Name = "Sheet33" Then '~As long as the sheet is not Sheet33, fire the search,copy,paste function below
actvLrow = ws.Range("A" & Rows.Count).End(xlUp).Row '~ Set the lastrow of the active sheet
For Each actvCell In ws.Range("C1:C" & actvLrow) '~ Loop through the cells of column C
If actvCell.Value = "Power On" Then '~Look for criteria
ws.Rows(actvCell.Row & ":" & actvCell.Row).Copy '~Copy the row that matches the criteria
nrow = wsResult.Range("A" & Rows.Count).End(xlUp).Offset(1).Row '~Get the lastrow empty row of the output sheet
wsResult.Range("A" & nrow).PasteSpecial xlPasteValuesAndNumberFormats '~Paste to the next empty row
Application.CutCopyMode = False
End If
Next actvCell
End If
Next ws
Application.ScreenUpdating = True
End Sub
' The reason you are getting the same sheet is you are setting WS1 to ActiveSheet
' 31 times in a row -- not getting the first 31 sheets.
' ActiveSheet is whatever sheet you last happened to have in focus. Unless you
' know you want that (almost never), you should not use it.
' You want to avoids things like copy / paste / select. These are slow.
' You also want to avoid processing things row by row.
' Here is an example that should do what you want.
Sub ThirtyOneFlavors()
Const PowerColNum = 3 ' if you are sure it will always be column 3
Dim WS1 As Worksheet, WS33 As Worksheet
Dim PowerColumn As Range, PowerCell As Range, FirstCell As Range, R As Long
Set WS33 = ThisWorkbook.Sheets("Sheet33") ' Maybe this could use a clever name
WS33.Cells.Delete ' only if you want this
' using ThisWorkbook avoids accidentally getting some other open workbook
For Each WS1 In ThisWorkbook.Sheets
' here, put the names of any sheets you don't want to process
If WS1.Name <> WS33.Name Then
Set PowerColumn = WS1.UsedRange.Columns(PowerColNum)
' I am assuming Power On is the whole column
Set PowerCell = PowerColumn.Find("Power On", LookIn:=xlValues, lookat:=xlWhole, MatchCase:=False)
If Not PowerCell Is Nothing Then ' if you found something
' we need to keep track of the first one found,
' otherwise Excel will keep finding the same one repeatedly
Set FirstCell = PowerCell
End If
While Not PowerCell Is Nothing ' if you keep finding cells
R = R + 1 ' next row
'.Value will hold all of the values in a range (no need to paste)
WS33.Cells(R, 1).EntireRow.Value = PowerCell.EntireRow.Value
' get the next one
Set PowerCell = PowerColumn.Find("Power On", after:=PowerCell, LookIn:=xlValues, lookat:=xlWhole, MatchCase:=False)
If PowerCell.Address = FirstCell.Address Then
' if we found the first one again, kill the loop
Set PowerCell = Nothing
End If
Wend
End If
Next WS1
End Sub
'Consolidate' Data
Option Explicit
Sub ConsolidateData()
' Source
Const sfIndex As Long = 1
Const slIndex As Long = 31
Const sFirstCell As String = "C2"
Const sCriteria As String = "Power On"
' Destination
Const dIndex As Long = 33
Const dFirstCell As String = "A2" ' has to be column 'A' ('EntireRow')
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Create a reference to the initial destination cell.
Dim dws As Worksheet: Set dws = wb.Worksheets(dIndex)
Dim dfCell As Range: Set dfCell = dws.Range(dFirstCell)
Dim dCell As Range: Set dCell = RefLastCellInColumn(dfCell)
If dCell Is Nothing Then ' no data found
Set dCell = dfCell
Else ' data found
Set dCell = dCell.Offset(1)
End If
Dim sws As Worksheet
Dim srg As Range
Dim scrg As Range
Dim sCell As Range
Dim n As Long
Application.ScreenUpdating = False
' Process each source worksheet...
For n = sfIndex To slIndex
Set sws = wb.Worksheets(n)
Set scrg = RefColumn(sws.Range(sFirstCell))
' Test for data...
If Not scrg Is Nothing Then ' data in column found
' Process each cell in source column range...
For Each sCell In scrg.Cells
' Check current cell agains criteria. To ignore case,
' i.e. 'POWER ON = power on', 'vbTextCompare' is used.
If StrComp(CStr(sCell.Value), sCriteria, vbTextCompare) = 0 Then
' Combine current cell into current source range.
' The combining is restricted to per worksheet ('Union').
Set srg = RefCombinedRange(srg, sCell)
End If
Next sCell
' Test for matches...
If Not srg Is Nothing Then ' match found
' Copy. This will work only if all source cells contain values.
' If some of them contain formulas, the results may be mixed
' (some rows containing the formulas, some only values) due to
' the source range being non-contiguous.
' This is prevented by either not combining the cells or
' by using 'PasteSpecial'.
srg.EntireRow.Copy dCell
' Create a reference to the next destination cell.
Set dCell = dCell.Offset(srg.Cells.Count)
' Unreference source range (before processing next worksheet).
Set srg = Nothing
'Else ' no match found
End If
'Else ' no data in column found
End If
Next n
' Activate destination worksheet.
'If Not dws Is ActiveSheet Then dws.Activate
' Save workbook.
'wb.Save
Application.ScreenUpdating = True
MsgBox "Data consolidated.", vbInformation, "Consolidate Data"
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Creates a reference to the bottom-most non-empty cell
' in the one-column range from the first cell ('FirstCell')
' through the bottom-most cell of the worksheet column.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function RefLastCellInColumn( _
ByVal FirstCell As Range) _
As Range
If FirstCell Is Nothing Then Exit Function
With FirstCell.Cells(1)
Dim lCell As Range
Set RefLastCellInColumn = .Resize(.Worksheet.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
End With
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Creates a reference to the one-column range from the first cell
' of a range ('FirstCell') to the bottom-most non-empty cell
' of the first cell's worksheet column.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function RefColumn( _
ByVal FirstCell As Range) _
As Range
If FirstCell Is Nothing Then Exit Function
With FirstCell.Cells(1)
Dim lCell As Range
Set lCell = .Resize(.Worksheet.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
If lCell Is Nothing Then Exit Function
Set RefColumn = .Resize(lCell.Row - .Row + 1)
End With
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Creates a reference to a range combined from two ranges.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function RefCombinedRange( _
ByVal CombinedRange As Range, _
ByVal AddRange As Range) _
As Range
If CombinedRange Is Nothing Then
Set RefCombinedRange = AddRange
Else
Set RefCombinedRange = Union(CombinedRange, AddRange)
End If
End Function
An alternative method using Find and `FindNext'
Option Explicit
Sub test()
Const MAX_SHT = 3
Const PASTE_SHT = 4
Const TERM = "Power On"
Const COL = "C"
Dim wb As Workbook, ws As Worksheet
Dim n As Integer, LastRow As Long, count As Long
Dim rngFound As Range, rngTarget As Range, sFirst As String
Set wb = ThisWorkbook
' check number of sheets
If wb.Sheets.count < MAX_SHT Then
MsgBox "Too few sheets", vbCritical
Exit Sub
End If
' copy destination
With wb.Sheets(PASTE_SHT)
LastRow = .Cells(Rows.count, COL).End(xlUp).Row
Set rngTarget = .Cells(LastRow + 1, "A")
End With
' first 31 sheets
For n = 1 To MAX_SHT
Set ws = wb.Sheets(n)
LastRow = ws.Cells(Rows.count, COL).End(xlUp).Row
With ws.Range("C1:C" & LastRow)
' search for term
Set rngFound = .Find(TERM, lookin:=xlValues, LookAt:=xlWhole)
If Not rngFound Is Nothing Then
sFirst = rngFound.Address
Do
ws.Rows(rngFound.Row).EntireRow.Copy rngTarget
Set rngTarget = rngTarget.Offset(1)
Set rngFound = .FindNext(rngFound)
count = count + 1
Loop While rngFound.Address <> sFirst
End If
End With
Next
MsgBox count & " rows copied", vbInformation
End Sub
ok just try the following code
many fixes are made and speedUps
Sub test()
' in a x64 environement better forget Integers and go for Longs
Dim LSearchRow As Long
Dim LCopyToRow As Long
Dim ws1 As Worksheet
Dim I As Long
Dim vldRng As Range
Dim maxRw As Long
Dim maxClmn As Long
Dim rngDest As Range
'2 Lines to speed code Immensly. Don't use them while debugging
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
LCopyToRow = 1
Set rngDest = ThisWorkbook.Sheets("Sheet33").Cells(1, 1)
'Set rngDest = ThisWorkbook.Sheets(33).Range("A1") 'Alternative 01
'Set rngDest = Sheets(33).Range("A1") 'Alternative 02
For I = 1 To 31
Set ws1 = ThisWorkbook.Sheets(I)
Set vldRng = ws1.UsedRange ' Get range used instead of searching entire Sheet
maxRw = vldRng.Rows.Count
maxClmn = vldRng.Columns.Count
For LSearchRow = 1 To maxRw
'If value in column C = "Power On", copy entire row to Sheet33
If vldRng.Cells(LSearchRow, 3).Value = "Power On" Then
'Select row in ws1 to copy
vldRng.Cells(LSearchRow, 1).Resize(1, maxClmn).Copy
'Paste row into Sheet33 in next row
rngDest.Offset(LCopyToRow - 1, 0).PasteSpecial xlPasteValues
LCopyToRow = LCopyToRow + 1
End If
Next LSearchRow
Next I
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub

Merging Multiple Worksheets To Single Worksheet In Different Workbook

I want to copy all the rows and columns in multiple worksheets in a one workbook to a single worksheet in a different workbook. In addition, I just want to copy the header once, even though it is in all of the worksheets I'll copy.
I can open the workbook containing all of the worksheets I want to copy to my destination worksheet/workbook however, I don't know how to copy the header only once and often get a Paste Special error.
Sub Raw_Report_Import()
'Define variables'
Dim ws As Worksheet
Dim wsDest As Worksheet
'Set target destination'
Set wsDest = Sheets("Touchdown")
'For loop to copy all data except headers'
For Each ws In ActiveWorkbook.Sheets
'Ensure worksheet name and destination tab do not have same name'
If ws.Name <> wsDest.Name Then
ws.Range("A2", ws.Range("A2").End(xlToRight).End(xlDown)).Copy
wsDest.Cells(Rows.Count, "A").End(xlUp).Offset(1).PasteSpecial xlPasteValues
End If
Next ws
End Sub
Expected: All of the target worksheets from second workbook are copied and pasted to destination worksheet "Touchdown" in first workbook and the header is copied only once.
Actual: Some values are paste but the formatting is wrong from what they were and it is not lining up correctly.
There are a number of things wrong with your code. Please find below code (not tested). Please note the differences so you can improve.
Note, when setting the destination worksheet, I would include the workbook object (if in a different workbook). This will prevent errors from occurring. Also note that this code should be run in the OLD workbook. Additionally, I assume your headers are in Row 1 in each sheet, as such I have included headerCnt to take this into consideration and only copy the headers once.
Option Explicit
Sub Raw_Report_Import()
Dim ws As Worksheet
Dim wsDest As Worksheet
Dim lCol As Long, lRow As Long, lRowTarget As Long
Dim headerCnt As Long
'i would include the workbook object here
Set wsDest = Workbooks("NewWorkbook.xlsx").Sheets("Touchdown")
For Each ws In ThisWorkbook.Worksheets
'this loops through ALL other sheets that do not have touch down name
If ws.Name <> wsDest.Name Then
'need to include counter to not include the header
'establish the last row & column to copy
lCol = ws.Cells(2, ws.Columns.Count).End(xlToLeft).Column
lRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
'establish the last row in target sheet
lRowTarget = wsDest.Range("A" & wsDest.Rows.Count).End(xlUp).Row + 1
If headerCnt = 0 Then
'copy from Row 1
ws.Range(ws.Cells(1, 1), ws.Cells(lRow, lCol)).Copy
Else
'copy from row 2
ws.Range(ws.Cells(2, 1), ws.Cells(lRow, lCol)).Copy
End If
wsDest.Range("A" & lRowTarget).PasteSpecial xlPasteValues
'clear clipboard
Application.CutCopyMode = False
'header cnt
headerCnt = 1
End If
Next ws
End Sub
Try it like this.
Sub CopyDataWithoutHeaders()
Dim sh As Worksheet
Dim DestSh As Worksheet
Dim Last As Long
Dim shLast As Long
Dim CopyRng As Range
Dim StartRow As Long
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'Delete the sheet "RDBMergeSheet" if it exist
Application.DisplayAlerts = False
On Error Resume Next
ActiveWorkbook.Worksheets("RDBMergeSheet").Delete
On Error GoTo 0
Application.DisplayAlerts = True
'Add a worksheet with the name "RDBMergeSheet"
Set DestSh = ActiveWorkbook.Worksheets.Add
DestSh.Name = "RDBMergeSheet"
'Fill in the start row
StartRow = 2
'loop through all worksheets and copy the data to the DestSh
For Each sh In ActiveWorkbook.Worksheets
If sh.Name <> DestSh.Name Then
'Find the last row with data on the DestSh and sh
Last = LastRow(DestSh)
shLast = LastRow(sh)
'If sh is not empty and if the last row >= StartRow copy the CopyRng
If shLast > 0 And shLast >= StartRow Then
'Set the range that you want to copy
Set CopyRng = sh.Range(sh.Rows(StartRow), sh.Rows(shLast))
'Test if there enough rows in the DestSh to copy all the data
If Last + CopyRng.Rows.Count > DestSh.Rows.Count Then
MsgBox "There are not enough rows in the Destsh"
GoTo ExitTheSub
End If
'This example copies values/formats, if you only want to copy the
'values or want to copy everything look below example 1 on this page
CopyRng.Copy
With DestSh.Cells(Last + 1, "A")
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
End With
End If
End If
Next
ExitTheSub:
Application.Goto DestSh.Cells(1)
'AutoFit the column width in the DestSh sheet
DestSh.Columns.AutoFit
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
All details are here.
https://www.rondebruin.nl/win/s3/win002.htm

vba macro to paste data from multiple sheets one after another

I have an excel workbook that has invoice data for every month with an identical layout. I was wondering if there is a macro that can copy the data from each sheet and paste it all one after the other.
So the first sheet is P1, then P2, P3 etc until P12. I want a macro that will paste P1 data onto a new sheet, then P2 data right underneath it, then P3 etc until the end.
I imagine this would be some sort of For loop, but I'm not sure what the code would look like (I'm very new to vba)
Thank you in advance!!!
How about this option?
Sub CopyDataWithoutHeaders()
Dim sh As Worksheet
Dim DestSh As Worksheet
Dim Last As Long
Dim shLast As Long
Dim CopyRng As Range
Dim StartRow As Long
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'Delete the sheet "RDBMergeSheet" if it exist
Application.DisplayAlerts = False
On Error Resume Next
ActiveWorkbook.Worksheets("RDBMergeSheet").Delete
On Error GoTo 0
Application.DisplayAlerts = True
'Add a worksheet with the name "RDBMergeSheet"
Set DestSh = ActiveWorkbook.Worksheets.Add
DestSh.Name = "RDBMergeSheet"
'Fill in the start row
StartRow = 2
'loop through all worksheets and copy the data to the DestSh
For Each sh In ActiveWorkbook.Worksheets
If sh.Name <> DestSh.Name Then
'Find the last row with data on the DestSh and sh
Last = LastRow(DestSh)
shLast = LastRow(sh)
'If sh is not empty and if the last row >= StartRow copy the CopyRng
If shLast > 0 And shLast >= StartRow Then
'Set the range that you want to copy
Set CopyRng = sh.Range(sh.Rows(StartRow), sh.Rows(shLast))
'Test if there enough rows in the DestSh to copy all the data
If Last + CopyRng.Rows.Count > DestSh.Rows.Count Then
MsgBox "There are not enough rows in the Destsh"
GoTo ExitTheSub
End If
'This example copies values/formats, if you only want to copy the
'values or want to copy everything look below example 1 on this page
CopyRng.Copy
With DestSh.Cells(Last + 1, "A")
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
End With
End If
End If
Next
ExitTheSub:
Application.Goto DestSh.Cells(1)
'AutoFit the column width in the DestSh sheet
DestSh.Columns.AutoFit
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Function LastRow(sh As Worksheet)
On Error Resume Next
LastRow = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
End Function
Function LastCol(sh As Worksheet)
On Error Resume Next
LastCol = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
End Function
https://www.rondebruin.nl/win/s3/win002.htm
Because details are very limited in order to get an idea of the sheets' structure i try to create general code which with some modifications will satisfy your needs.
Option Explicit
Sub test()
Dim wsTest As Worksheet, ws As Worksheet
Dim LRW As Long, LRF As Long, LCW As Long
'Here we create a separate sheet namded wsFull to paste the data in it.
Set wsTest = Nothing
On Error Resume Next
Set wsTest = ActiveWorkbook.Worksheets("wsFull")
On Error GoTo 0
If wsTest Is Nothing Then
Worksheets.Add.Name = "wsFull"
End If
Set wsTest = ActiveWorkbook.Worksheets("wsFull")
'Here we loop all sheets except the new sheet named wsFull
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> "wsFull" Then
With ws
'Here we find last column (using first row) & last row (using Column A) for each sheet we loop
LRW = .Cells(.Rows.Count, "A").End(xlUp).Row
LCW = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
'Here we find the last row of wsFull in order to find where we will paste the data in.
LRF = wsTest.Cells(wsTest.Rows.Count, "A").End(xlUp).Row
'We paste the data in column A
If LRF = 1 And wsTest.Range("A1").Value = "" Then
ws.Range(ws.Cells(1, 1), ws.Cells(LRW, LCW)).Copy wsTest.Range("A1")
Else
ws.Range(ws.Cells(1, 1), ws.Cells(LRW, LCW)).Copy wsTest.Range("A" & LRF + 1)
End If
End If
Next ws
End Sub

Copy specified columns to a worksheet based on value in column A

I have the following which works ok but instead of copying the entire row from the "Combined" worksheet to the "Summary" worksheet I only want to copy columns A to T. This is a first attempt so any help would be gratefully received!
`Private Sub CommandButton1_Click()
'Define Variables
Dim DestSh As Worksheet
Dim s As Worksheet
Dim c As Integer
Dim i
Dim LastRow
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'Delete the Combined sheet if it exists
Application.DisplayAlerts = False
On Error Resume Next
ActiveWorkbook.Worksheets("Combined").Delete
On Error GoTo 0
Application.DisplayAlerts = True
'Add a new Combined worksheet
Set DestSh = ActiveWorkbook.Worksheets.Add
DestSh.Name = "Combined"
'Select Summary worksheet and copy headings and column widths to Combined worksheet
Sheets("Summary").Activate
Range("A24").EntireRow.Select
Selection.Copy Destination:=Sheets("Combined").Range("A1")
For c = 1 To Sheets("Summary").Columns.Count
Sheets("Combined").Columns(c).ColumnWidth = Sheets("Summary").Columns(c).ColumnWidth
Next
'Loop through all worksheets sheets that begin with ra
'and copy to the combined worksheet
For Each s In ActiveWorkbook.Sheets
If LCase(Left(s.Name, 2)) = "ra" Then
Application.Goto Sheets(s.Name).[A1]
Selection.Range("A23:Q50").Select
Selection.Copy Destination:=Sheets("Combined"). _
Cells(Rows.Count, 1).End(xlUp)(2)
End If
Next
'Copy all rows that contain Yes in column A to Summary worksheet
LastRow = Sheets("Combined").Range("A" & Rows.Count).End(xlUp).Row
Sheets("Summary").Range("A25:V500").ClearContents
For i = 1 To LastRow
If Sheets("Combined").Cells(i, "A").Value = "Yes" Then
Sheets("Combined").Cells(i, "A").EntireRow.Copy Destination:=Sheets("Summary").Range("A" & Rows.Count).End(xlUp).Offset(1)
End If
Next i
'Force return to Summary worksheet
Worksheets("Summary").Activate
End Sub
You can use the .Resize() method to change the range that is copied. Replace your line where you copy and paste it to the new destination with this one and it should work:
Sheets("Combined").Cells(i, "A").Resize(1, 20).Copy Destination:=Sheets("Summary").Range("A" & Rows.Count).End(xlUp).Offset(1)

VBA Code error in copying data from multiple WS to consolidated sheet

I wanted to copy the data from multiple sheets to a single sheet. Data range in multiple sheets keep varying, so I will have to copy whatever data is in the WS and paste it to the consolidated WS. My VBA Code is giving me an error stating, compilation error "Expected Array" at "Last = LastRow(DestSh)". Can someone please help me how to correct this?
Sub Consolidatedata()
Dim sh As Worksheet
Dim DestSh As Worksheet
Dim Last As Long
Dim shLast As Long
Dim CopyRng As Range
Dim StartRow As Long
Dim LastRow As Long
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
' Delete the summary sheet if it exists.
Application.DisplayAlerts = False
On Error Resume Next
ActiveWorkbook.Worksheets("Consolidated").Delete
On Error GoTo 0
Application.DisplayAlerts = True
' Add a new summary worksheet.
Set DestSh = ActiveWorkbook.Worksheets.Add
DestSh.Name = "Consolidated"
' Fill in the start row.
StartRow = 2
' Loop through all worksheets and copy the data to the
' summary worksheet.
For Each sh In ActiveWorkbook.Worksheets
If sh.Name <> DestSh.Name Then
' Find the last row with data on the summary
' and source worksheets.
Last = LastRow(DestSh)
shLast = LastRow(sh)
' If source worksheet is not empty and if the last
' row >= StartRow, copy the range.
If shLast > 0 And shLast >= StartRow Then
'Set the range that you want to copy
Set CopyRng = sh.Range(sh.Rows(StartRow), sh.Rows(shLast))
' Test to see whether there are enough rows in the summary
' worksheet to copy all the data.
If Last + CopyRng.Rows.Count > DestSh.Rows.Count Then
MsgBox "There are not enough rows in the " & _
"summary worksheet to place the data."
GoTo ExitTheSub
End If
' This statement copies values and formats.
CopyRng.Copy
With DestSh.Cells(Last + 1, "A")
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
End With
End If
End If
Next
ExitTheSub:
Application.Goto DestSh.Cells(1)
' AutoFit the column width in the summary sheet.
DestSh.Columns.AutoFit
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
LastRow is declared as a Long around line 8 in the code supplied. So it just has a numerical value, which defaults to zero.
I'm guessing you may also have a LastRow function, probably looking something like this?
Function LastRow(sh As WorkSheet) As Long
Try removing this line:
Dim LastRow As Long

Resources