Copy/Paste Loop through worksheets to consolidate - excel

I have a workbook which has approximately 300 worksheets. I'm trying to loop through each sheet, copy a specific range, and paste it on summary sheet. I need each successive paste to be put one row below the last used row. I'm newer to loops, but I think the amount of information being copied is excessive(causing an error), and I have come to understand that the .value method is much less memory intensive.
How do I incorporate the .value method to accomplish this? Here is the code I tried to write (again, I'm new to coding,sorry).
Sub Consolidation()
Dim ws As Worksheet
Sheets("Summary").Select
For Each ws InThisWorkbook.Sheets
ActiveSheet.Range("A" & Rows.Count).End(xLUp).Offset(1).Value ="ws.Range("BB1").End(xLToRight).End(xLDown).Select"
Next ws
End Sub
Alternatively, is there a better way to do this? Meaning, is the .value method the way to tackle this issue?

This question is similar than:
Simple Copy/Paste Loop not working on each worksheet
This is the way you can use the .Value
Sub WsLoop()
Dim ws As Worksheet
Dim Summary As Worksheet
Set Summary = ThisWorkbook.Sheets("Summary")
For Each ws In ThisWorkbook.Sheets
If Not ws.Name = "Summary" Then 'This will skip Summary.
Summary.Range("A1").Value = ws.Range("A1").Value
End If
Next ws
End Sub

Sub loop_through_all_worksheets_cpyPst()
Dim ws As Worksheet
Dim starting_ws As Worksheet
Set starting_ws = Sheets("startAtSheet")
'remember which worksheet is active in the beginning
For Each ws In ThisWorkbook.Worksheets
ws.Activate
If Not ws.Name = "SheettoPasteTo_skipCopy" Then 'This will skip Summary.
Range("A2:I2").Select
'my section range had only columns till i - edit the to last column
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Sheets("SheettoPasteTo_skipcopy").Select
'edit this sheet name to copy to
Range("A1").Select
Selection.End(xlDown).Select
ActiveCell.Offset(1, 0).Range("A1").Select
ActiveSheet.Paste
ActiveCell.Offset(1, 0).Range("A1").Select
Selection.End(xlDown).Select
End If
ws.Cells(1, 1) = 1 'this sets cell A1 of each sheet to "1"
Next
starting_ws.Activate
'activate the worksheet that was originally active
End Sub

Related

Copy and paste values only after filtering data in vba [duplicate]

I have two sheets. One has the complete data and the other is based on the filter applied on the first sheet.
Name of the data sheet : Data
Name of the filtered Sheet : Hoky
I am just taking a small portion of data for simplicity. MY objective is to copy the data from Data Sheet, based on the filter. I have a macro which somehow works but its hard-coded and is a recorded macro.
My problems are:
The number of rows is different everytime. (manual effort)
Columns are not in order.
Sub TESTTHIS()
'
' TESTTHIS Macro
'
'FILTER
Range("F2").Select
Selection.AutoFilter
ActiveSheet.Range("$B$2:$F$12").AutoFilter Field:=5, Criteria1:="hockey"
'Data Selection and Copy
Range("C3").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Sheets("Hockey").Select
Range("E3").Select
ActiveSheet.Paste
Sheets("Data").Select
Range("D3").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Hockey").Select
Range("D3").Select
ActiveSheet.Paste
Sheets("Data").Select
Range("E3").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Hockey").Select
Range("C3").Select
ActiveSheet.Paste
End Sub
Best way of doing it
Below code is to copy the visible data in DBExtract sheet, and paste it into duplicateRecords sheet, with only filtered values. Range selected by me is the maximum range that can be occupied by my data. You can change it as per your need.
Sub selectVisibleRange()
Dim DbExtract, DuplicateRecords As Worksheet
Set DbExtract = ThisWorkbook.Sheets("Export Worksheet")
Set DuplicateRecords = ThisWorkbook.Sheets("DuplicateRecords")
DbExtract.Range("A1:BF9999").SpecialCells(xlCellTypeVisible).Copy
DuplicateRecords.Cells(1, 1).PasteSpecial
End Sub
I suggest you do it a different way.
In the following code I set as a Range the column with the sports name F and loop through each cell of it, check if it is "hockey" and if yes I insert the values in the other sheet one by one, by using Offset.
I do not think it is very complicated and even if you are just learning VBA, you should probably be able to understand every step. Please let me know if you need some clarification
Sub TestThat()
'Declare the variables
Dim DataSh As Worksheet
Dim HokySh As Worksheet
Dim SportsRange As Range
Dim rCell As Range
Dim i As Long
'Set the variables
Set DataSh = ThisWorkbook.Sheets("Data")
Set HokySh = ThisWorkbook.Sheets("Hoky")
Set SportsRange = DataSh.Range(DataSh.Cells(3, 6), DataSh.Cells(Rows.Count, 6).End(xlUp))
'I went from the cell row3/column6 (or F3) and go down until the last non empty cell
i = 2
For Each rCell In SportsRange 'loop through each cell in the range
If rCell = "hockey" Then 'check if the cell is equal to "hockey"
i = i + 1 'Row number (+1 everytime I found another "hockey")
HokySh.Cells(i, 2) = i - 2 'S No.
HokySh.Cells(i, 3) = rCell.Offset(0, -1) 'School
HokySh.Cells(i, 4) = rCell.Offset(0, -2) 'Background
HokySh.Cells(i, 5) = rCell.Offset(0, -3) 'Age
End If
Next rCell
End Sub
When i need to copy data from filtered table i use range.SpecialCells(xlCellTypeVisible).copy. Where the range is range of all data (without a filter).
Example:
Sub copy()
'source worksheet
dim ws as Worksheet
set ws = Application.Worksheets("Data")' set you source worksheet here
dim data_end_row_number as Integer
data_end_row_number = ws.Range("B3").End(XlDown).Row.Number
'enable filter
ws.Range("B2:F2").AutoFilter Field:=2, Criteria1:="hockey", VisibleDropDown:=True
ws.Range("B3:F" & data_end_row_number).SpecialCells(xlCellTypeVisible).Copy
Application.Worksheets("Hoky").Range("B3").Paste
'You have to add headers to Hoky worksheet
end sub
it needs to be .Row.count not Row.Number?
That's what I used and it works fine
Sub TransfersToCleared()
Dim ws As Worksheet
Dim LastRow As Long
Set ws = Application.Worksheets("Export (2)") 'Data Source
LastRow = Range("A" & Rows.Count).End(xlUp).Row
ws.Range("A2:AB" & LastRow).SpecialCells(xlCellTypeVisible).Copy

Creating a macro to Unhide worksheets and Clear Used Rows, Resetting the workbook

I have a 52 sheet workbook that needs to be reset after the file is saved as a copy.
I have the UnHide part figured out, but I can't seem to figure out the Clearcontents.
On many Worksheets, not all, in row A there is a string "State Requires All License Verifications"
It is in a variable row, between 6 and 12. Starting with ws2 I want to find the string and clear the rows below it. Column range A:H
Then Check the next worksheet.
I have this so far..
Sub UnhideAllSheets()
Dim ws As Worksheet
Dim rowNum As Long
Dim stateReg As String
For Each ws In ActiveWorkbook.Worksheets
ws.Visible = xlSheetVisible
If ws.Visible Then
'Activate sheet
ws.Activate
'Look for String "State Requires All License Verifications"
Set stateReq = .Find(what:="State Requires All License Verifications")
'Null find quits loop
If Not stateReq Is Nothing Then
rowNum = stateReq.Row
End If
'Clear all Used rows after String(stateReq)
With Sheets(ws)
Intersect(.Range(.Rows(rowNum + 1), .UsedRange.Rows(.UsedRange.Rows.Count)), .Range("A:H")).ClearContents
End With
'Select and Zoom to A1 upon leaving the worksheet
Range("A1").Select
ActiveWindow.ScrollRow = 1
ActiveWindow.ScrollColumn = 1
End If
Next ws
'Jump back to the first worksheet "Information"
Sheets("Information").Select
Range("E2").Select
End Sub
Try this. Not sure where you got stuck.
I have assumed the string is in column A and that A is also a reliable indicator of the last used row (so may need changing).
Also no need to activate the sheet.
Sub UnhideAllSheets()
Dim ws As Worksheet
Dim rowNum As Long
Dim stateReg As Range
For Each ws In ActiveWorkbook.Worksheets
ws.Visible = xlSheetVisible
Set stateReg = ws.Columns(1).Find(what:="State Requires All License Verifications", Lookat:=xlWhole, MatchCase:=False, SearchFormat:=False)
If Not stateReg Is Nothing Then
Range(stateReg.Offset(1), ws.Range("A" & Rows.Count).End(xlUp)).Resize(, 8).ClearContents
End If
Next ws
'Jump back to the first worksheet "Information"
Application.Goto Sheets("Information").Range("E2")
End Sub
Maybe something like:
Sub Fresh_Slate()
Dim ws As Worksheet
Dim Found As Range
Dim Target As String
Dim lr As Long
Target = "State Requires All License Verifications"
For Each ws In ThisWorkbook.Sheets
If ws.Name <> "Sheet1" Then 'You can add sheets to ignore here
ws.Visible = xlSheetVisible
Set Found = ws.Cells.Find(Target)
If Not Found Is Nothing Then
'Assuming Column A on each sheet is a good indicator of the last used row in range
lr = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
ws.Range(ws.Cells(Found.Row + 1, 1), ws.Cells(lr, 8)).ClearContents
End If
Set Found = Nothing
End If
Next ws
End Sub

Copy Rows from Filtered Data and Insert into Existing Data

I am trying to copy rows of data (which may or may not be filtered) and INSERT it into rows above existing data (sort of a rolling schedule). Below is my code that works for unfiltered data. If I apply any filters to the data to be copied, my macro will only copy 1 cell. Can anyone provide an example of a macro that can copy both filtered and unfiltered data?
Sub DynamicRange()
'Best used when first column has value on last row and first row has a value in the last column
Dim sht As Worksheet
Dim LastRow As Long
Dim LastColumn As Long
Dim StartCell As Range
Dim SelectedRange As Range
Set sht = ActiveWorkbook.ActiveSheet
Set StartCell = Range("C9")
If IsEmpty(StartCell.Value) = True Then
MsgBox "Enter Dates to export"
Exit Sub
End If
'Find Last Row and Column
LastRow = sht.Cells(sht.Rows.Count, StartCell.Column).End(xlUp).Row
LastColumn = sht.Cells(StartCell.Row, sht.Columns.Count).End(xlToLeft).Column
'Select Range and Copy
Set SelectedRange = sht.Range(StartCell, sht.Cells(LastRow, LastColumn))
SelectedRange.Select
Selection.SpecialCells(xlCellTypeVisible).Select
Selection.Copy
'Select sheet "TRACKER" insert values above previous data
Sheets("TRACKER").Select
Range("B9").Select
Selection.Insert Shift:=xlDown
'clear selection
Application.CutCopyMode = False
End Sub
I've rewritten your sub procedure and tried to avoid the use of .Select and Selection. Relying on properties like the ActiveCell¹ and ActiveSheet¹ is haphazard at best.
Sub DynamicRange()
Dim sc As Range, sht As Worksheet
Set sht = ActiveWorkbook.Worksheets("Sheet1") '<~~ set this worksheet reference properly
'btw, if you really needed ActiveWorkbook here then you would need it with Worksheets("TRACKER") below.
With sht
Set sc = .Range("C9") 'don't really have a use for this
If IsEmpty(.Range("C9")) Then
MsgBox "Enter Dates to export"
Exit Sub
End If
With .Range(.Cells(9, 3), .Cells(9, Columns.Count).End(xlToLeft))
With Range(.Cells(1, 1), .Cells(Rows.Count, .Columns.Count).End(xlUp))
'got the range; determine non-destructively if anything is there
If CBool(Application.Subtotal(103, .Cells)) Then
'there are visible values in the cells
.Cells.Copy _
Destination:=Worksheets("TRACKER").Cells(Rows.Count, 2).End(xlUp).Offset(1, 0)
End If
End With
End With
End With
End Sub
The worksheet's SUBTOTAL function does not count hidden values so it is a good non-destructive test for the existence of visible values. You do not need to copy the Range.SpecialCells with the xlCellTypeVisible property specifically. A regular Range.Copy method will only copy visible cells. By immediately specifying the destination, there is no need to transfer the ActiveSheet property to the TRACKER worksheet; only the top-left corner of the destination need be specified.
¹ See How to avoid using Select in Excel VBA macros for more methods on getting away from relying on select and activate to accomplish your goals.

merge Excel sheets as values

I am using some code (found via: http://www.extendoffice.com/documents/excel/1184-excel-merge-multiple-worksheets-into-one.html) to merge 5 sheets, each with 1000 rows.
Sub Combine()
Dim J As Integer
On Error Resume Next
Sheets(1).Select
Worksheets.Add
Sheets(1).Name = "Combined"
Sheets(2).Activate
Range("A1").EntireRow.Select
Selection.Copy Destination:=Sheets(1).Range("A1")
For J = 2 To Sheets.Count
Sheets(J).Activate
Range("A1").Select
Selection.CurrentRegion.Select
Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Select
Selection.Copy Destination:=Sheets(1).Range("A65536").End(xlUp)(2)
Next
End Sub
This seems to work perfectly, other than I need to have the sheets combined using a 'paste as values' methodology (as my individual sheets have many formulas, and I just want to combine them as text versions).
Can this code be easily changed to 'paste as values'?
Thanks.
Sub Combine()
Dim J As Integer
On Error Resume Next
Sheets(1).Select
Worksheets.Add
Sheets(1).name = "Combined"
Sheets(2).Activate
Range("A1").EntireRow.Select
Selection.Copy Destination:=Sheets(1).Range("A1")
For J = 2 To Sheets.Count
Sheets(J).Activate
Range("A1").Select
Selection.CurrentRegion.Select
Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Copy
Sheets(1).Range("A65536").End(xlUp)(2).PasteSpecial xlPasteValues
Next
End Sub
Does this work? If so, we can get working on removing .select to make this a little bit more "tight". I already did it on the .Copy line (can you see what I did?)
Edit: This almost gets there - I think you'll hit an issue on the pasting part, but I can fix that. Just tell me, in your original code, what is the CurrentRegion that you're selecting? What's trying to be copy/pasted?
Edit 2: Okay, I think I've got it finally. The issue is your using Sheets(1), Sheets(2). I don't know how your document is, but the following works with these assumptions: You have the "unchanging" sheet active (this is the sheet with your magical formulas). Just have this active and run the macro below.
Sub Combine()
Dim J As Integer, noRows As Integer
Dim ws1 As Worksheet, ws2 As Worksheet, magicWS As Worksheet
' Note, you need to have the worksheet where you do all of your formulas open and be the active sheet.
Set magicWS = ActiveSheet
Set ws1 = Sheets.Add(after:=magicWS)
ws1.Name = "Combined"
On Error Resume Next
'Now, I assume that your main (unchanging) worksheet is the FAR LEFT most
'Then, the second worksheet is the new "Combined". If you look along the bottom, every worksheet RIGHT of "Combined" will need
'to be added to this WS.
'First, let's get the headers from the third sheet:
ws1.Cells.Rows(1).Value = Sheets(3).Cells.Rows(1).Value
'Now, let's add the data to "Combined"!
For J = 3 To Sheets.Count
noRows = Sheets(J).Range("A1").CurrentRegion.Rows.Count
Sheets(J).Range("A1").CurrentRegion.Offset(1, 0).Resize(noRows - 1).Copy
ws1.Range("A65536").End(xlUp)(2).PasteSpecial xlPasteValues
Next J
Application.CutCopyMode = False
End Sub

Looping through specific sheets in an excel work book and copying data in different work sheet

I'm trying to copy information from several specific sheets in a workbook, without copying information from irrelevant sheets, to a single sheet called Merge. The name of the sheets where i want to copy the information from is: Summary, Summary(1)... Summary(n+1).
In addition, i want the copied information to be pasted after the last row with information and without deleting the header line.
The code i'm using is a mix and match from various answers in different Excel-VBA forums so it's not elegant and probably has lots of errors caused by my limited understanding of VBA and coding as a whole.
This is the code i currently have:
Sub Copy_1()
Dim SourceRange As Range, DestRange As Range
Dim DestSheet As Worksheet, Lr As Long
With Application
.ScreenUpdating = False
.EnableEvents = False
.Calculation = xlCalculationManual
End With
'Deleting the information from sheet ñéëåí
Sheets("Merge").Select
Range("A2").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.ClearContents
'loop through all worksheets and copy the data to the DestSh
For Each sh In ThisWorkbook.Worksheets
'Loop through all worksheets except the Merge worksheet and the
'Information worksheet, you can add more sheets to the array if you want.
If IsError(Application.Match(sh.Name, _
Array(DestSheet.Name, "Merge"), 0)) Then
'fill in the Source Sheet and range
'Set SourceRange = Sheets("Summary").Range("A2:L100")
Set SourceRange = sh.Range("A2:N100")
SourceRange.Copy
'Fill in the destination sheet and call the LastRow
'function to find the last row
Set DestSheet = Sheets("øéëåæ")
Lr = LastRow(DestSheet)
'With the information from the LastRow function we can
'create a destination cell and copy/paste the source range
Set DestRange = DestSheet.Range("A" & Lr + 1)
'Set DestRange = DestSheet.Range("A" & Last + 1)
'End If
'SourceRange.Copy DestRange
SourceRange.Copy
With DestSheet.Cells(2, Last + 1)
.PasteSpecial 8 ' Column width
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
End With
Next
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = xlCalculationAutomatic
End With
End Sub
I would greatly appreciate your help as i've already spent hours going through various answers on similar issues in different forums and trying to solve this on my own.
Thanks a lot!
Check it out,
Sub Button1_Click()
Dim ws As Worksheet, sh As Worksheet, pRng As Range
Set ws = Sheets("Merge")
For Each sh In Sheets
If sh.Name <> ws.Name Then 'if sheet name does not ="Merge"
If sh.Name <> "Jimmy Changa" Then 'just an example if you didn't want to include a sheet
sh.Range("A2:N100").Copy
Set pRng = ws.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)
pRng.PasteSpecial Paste:=xlPasteFormats
pRng.PasteSpecial Paste:=xlPasteValues
End If
End If
Application.CutCopyMode = 0
Next sh
Columns("A:G").EntireColumn.AutoFit
End Sub

Resources