Skiping Multiple sheets in a Workbook - excel

I need a code for skipping Multiple worksheets and go to the next sheet in excel
I tried using select case and if array but it won't work
Sub s()
Select Case Sheet
Case Is = "Weekly Spread (%),Weekly spread (Count)Summary,Sheet1,Consolidated_Data"
Case Else
t = 0
Sheet.Select
If t = 1 Then
Range("a1").Select
Range(Selection, Selection.End(xlToRight).End(xlDown)).Copy
Else
Range("a2").Select
Range(Selection, Selection.End(xlToRight).End(xlDown)).Copy
End If
Sheets("LoginData").Select
If t = 1 Then
Range("a1").Select
Selection.PasteSpecial xlPasteValues
Else
Range("A1").Select
Selection.End(xlDown).Offset(1, 0).Select
Selection.PasteSpecial xlPasteValues
End If
End Select
t = t + 1
End Sub

Import Table Values
Option Explicit
Sub ImportData()
Dim Exceptions(): Exceptions = Array("LoginData", "Weekly Spread (%)", _
"Weekly spread (Count)Summary", "Sheet1", "Consolidated_Data")
Dim wb As Workbook: Set wb = ThisWorkbook
Dim dws As Worksheet: Set dws = wb.Sheets("LoginData")
'dws.Cells.Clear ' clear previous data
Dim dCell As Range: Set dCell = dws.Range("A1") ' first
Dim sws As Worksheet, srg As Range, IsFirstFound As Boolean
For Each sws In wb.Worksheets ' '.Sheets' would include charts!
If IsError(Application.Match(sws.Name, Exceptions, 0)) Then ' not found
If IsFirstFound Then ' it's not the first; exclude headers
With sws.Range("A1").CurrentRegion
Set srg = .Resize(.Rows.Count - 1).Offset(1)
End With
Else ' it's the first; include headers
Set srg = sws.Range("A1").CurrentRegion
IsFirstFound = True
End If
dCell.Resize(srg.Rows.Count, srg.Columns.Count).Value = srg.Value
Set dCell = dCell.Offset(srg.Rows.Count) ' next
'Else ' found; it's one from the exceptions array; do nothing
End If
Next sws
MsgBox "Data imported into """ & dws.Name & """.", vbInformation
End Sub
Some Thoughts on Your Code
Sub s()
' Next time show us the variable declarations and the For Each...Next loop.
Dim Sheet As Worksheet
Dim t As Long ' it is already 0; my code uses a boolean 'IsFirstFound'.
For Each Sheet In ThisWorkbook.Worksheets
Select Case Sheet
' This was a major mistake. Also, 'LoginData' had to be included.
' Also, keep in mind that this is case sensitive i.e. e.g. 'sheet1'
' will not be excluded. In my code 'Application.Match' is used
' on an array of the names which is not case sensitive.
Case "LoginData", "Weekly Spread (%)", _
"Weekly spread (Count)Summary", "Sheet1", "Consolidated_Data"
Case Else
' No need to use 'Select'. Use the 'With' statement instead.
' Best use variables to reference the workbook, worksheets
' and ranges. See 'wb', 'sws', 'dws', 'srg' and 'dCell' in my code.
' You needed to switch 'A1' and 'A2', or use 'If t = 0 Then'.
' It is very risky to use 'xlToRight' and 'xlDown' with 'A2' i.e.
' if a single cell in row 2 is empty, the wrong range
' will be referenced. The same goes for 'xlDown' in column 'A'
' while pasting.
' See the use of 'CurrentRegion', 'Resize' and 'Offset' in my code.
' Copying by assignment is faster and doesn't mess with
' the selection like 'PasteSpecial' does.
' The following two blocks of code are highly unreliable.
' You could call it a first step in getting rid of 'Select'.
With Sheet
If t = 0 Then ' first worksheet
.Range(.Range("A1"), .Range("A1").End(xlToRight).End(xlDown)).Copy
Else ' all but the first worksheet
.Range(.Range("A2"), .Range("A2").End(xlToRight).End(xlDown)).Copy
End If
End With
With ThisWorkbook.Sheets("LoginData")
If t = 0 Then ' first worksheet
.Range("A1").PasteSpecial xlPasteValues
Else ' all but the first worksheet
.Range("A1").End(xlDown).Offset(1, 0).PasteSpecial xlPasteValues
End If
End With
End Select
t = 1 ' since 'If T = 0 Then' is used (switches to all but the first)
Next Sheet
' There are too many issues for such a code to be reliable!
' It will work until it doesn't which may be sooner than you expect.
End Sub

Code changed assuming you want to iterate the sheets on the current workbook. I think you need to add LoginData to the list to avoid copying data from the same sheet.
Sub s()
For Each Sheet In ThisWorkbook.Sheets
Select Case Sheet.Name
' I think yo need to add LoginData to this list to avod copying into itself
Case "Weekly Spread (%)", "Weekly spread (Count)Summary", "Sheet1", "Consolidated_Data"
Case Else
t = 0
Sheet.Select
If t = 1 Then 'Why the difference here? I do understand it in the paste but not here
Range("a1").Select
Range(Selection, Selection.End(xlToRight).End(xlDown)).Copy
Else
Range("a2").Select
Range(Selection, Selection.End(xlToRight).End(xlDown)).Copy
End If
Sheets("LoginData").Select
If t = 1 Then
Range("a1").Select
Selection.PasteSpecial xlPasteValues
Else
Range("A1").Select
Selection.End(xlDown).Offset(1, 0).Select
Selection.PasteSpecial xlPasteValues
End If
End Select
t = t + 1
Next Sheet
End Sub

Related

Copy specified columns in particular order

I have 80 or so columns of data. I need just 21 columns.
In my output, I would like the 21 columns to be in a particular order. For example, I want the value from the cell AX2 from my source file to go to A2, BW2 to go to B2, etc.
The source data may differ from month to month and could have as little as 1 row of data or hundreds so I would like this to loop until no data is left.
I got a run time error 424 object required. I have only outlined the rules for two columns but will work on the rest when I get the proper set up.
Sub Macro1()
'
' Macro1 Macro
'
'
Sheet4.Select
Application.ScreenUpdating = False
row_count = 2
Do While Sheet2.Range("A" & row_count) <> ""
Range("AX2:AX1000").Select
Selection.Copy
ActiveWindow.ActivateNext
Range("A").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
ActiveWindow.ActivateNext
Range("BW2:BW1000").Select
Application.CutCopyMode = False
Selection.Copy
ActiveWindow.ActivateNext
Range("B").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
x = x + 1
ActiveWindow.ActivateNext
ActiveSheet.Next.Select
ActiveSheet.Next.Select
Loop
End Sub
I hope I didn't go too far. Try this subscript, it asks you to select a workbook, it will open the workbook, copy column B2 to last used Row on Column B, and paste it on the first workbook. Make sure to rename the CopyFromSheet and CopyToSheet on the code. Please read each line and try to understand what it is doing. Let me know if any questions.
Sub CopyPaste()
Dim openFile As FileDialog, wb As Workbook, sourceWb As Workbook
Dim CopyTo As String, CopyFrom As String
Dim lastRow As Long
Application.ScreenUpdating = False
Set wb = ThisWorkbook
Set openFile = Application.FileDialog(msoFileDialogFilePicker)
openFile.Title = "Select Source File"
openFile.Filters.Clear
openFile.Filters.Add "Excel Files Only", "*.xl*"
openFile.Filters.Add "All Files", "*.*"
openFile.Show
If openFile.SelectedItems.Count <> 0 Then
Set sourceWb = Workbooks.Open(openFile.SelectedItems(1), False, True, , , , True)
CopyFrom = "CopyFromSheetName"
CopyTo = "CopyToSheetName"
lastRow = sourceWb.Sheets(CopyFrom).Cells(Rows.Count, "B").End(Excel.xlUp).Row
sourceWb.Sheets(CopyFrom).Range("B2:B" & lastRow).Copy 'You can copy this Row and the Next and add as many as you want to copy the Columns Needed
wb.Sheets(CopyTo).Range("B1").PasteSpecial xlValues
Application.CutCopyMode = xlCopy
Else
MsgBox "A file was not selected"
End If
Application.ScreenUpdating = True
End Sub
I suggest you separate the copy logic from the setup of which columns to copy. That way it will be much easier to manage the setup.
In this code I have hard coded to Columns Pairs. Alternatively, you could put that data on a sheet and read it in.
Sub Demo()
'declare all your variables
Dim wsSource As Worksheet
Dim wsDest As Worksheet
Dim rSource As Range
Dim rDest As Range
Dim CP() As Variant 'Column Pairs array
Dim idx As Long
'Set up an array of Source and Destination columns
ReDim CP(1 To 21, 1 To 2) 'Adjust size to suit number of column pairs
CP(1, 1) = "AX": CP(1, 2) = "A"
CP(2, 1) = "BW": CP(2, 2) = "B"
'and so on
' Source and Destination don't have to be in the same Workbook
' This code assumes the Source (and Destination) worksbooks are already open
' You can add code to open them if required
' If the data is in the same book as the code, use ThisWorkbook
' If the data is in a different book from the code,
' specify the book like Application.Workbooks("BookName.xlsx")
' or use ActiveWorkbook
'Update the names to your sheet names
Set wsSource = ThisWorkbook.Worksheets("SourceSheetName")
Set wsDest = ThisWorkbook.Worksheets("DestSheetName")
' Notice that form here on the code is independent of the Sheet and Column names
'Loop the column pairs array
For idx = 1 To UBound(CP, 1)
'if the entry is not blank
If CP(idx, 1) <> vbNullString Then
'Get reference to source column cell on row 2
Set rSource = wsSource.Columns(CP(idx, 1)).Cells(2, 1)
'If that cell is not empty
If Not IsEmpty(rSource) Then
'If the next cell is not empty
If Not IsEmpty(rSource.Offset(1, 0)) Then
'extend range down to first blank cell
Set rSource = wsSource.Range(rSource, rSource.End(xlDown))
End If
'Get a reference to the destination range, from row 2, same size as source
Set rDest = wsDest.Columns(CP(idx, 2)).Cells(2, 1).Resize(rSource.Rows.Count)
'Copy the values
rDest.Value = rSource.Value
End If
End If
Next
End Sub

If Condition to create sheets only when Auto filter has data

I have written a code which does the below steps.
1) Loops through a list of products
2) Auto filters the data with each product.
3) Copies and pastes data on to separate worksheets and names it with that product name.
4) Inserts a line at every change in schedule
The only thing I couldn't do it here is to limit separate worksheet creation only for the products available in the source data when auto filtered.
I tried to do this by adding an if condition to add worksheets by product name only if auto filter shows any data but for some reason it is not working.
I would appreciate any help in fixing this problem and clean my code to make it look better and work faster.
Sub runreport()
Dim rRange As Range
Dim Rng As Range
' Open the Source File
Filename = Application.GetOpenFilename()
Workbooks.Open Filename
'Loops through each product type range from the macro spreadsheet.
For Each producttype In ThisWorkbook.Sheets("Schedule").Range("Product")
' Filters the sheet with a product code that matches and copy's the active sheet selection
Workbooks("Source.xlsx").Sheets("Sheet1").Range("A1:G1").AutoFilter Field:=4, Criteria1:=producttype
Sheets("Sheet1").Select
Sheets("Sheet1").Select
Range("A2").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
'Adds a new workbook
ActiveWorkbook.Sheets.Add After:=ActiveWorkbook.Sheets(Sheets.Count)
'Names the worksheet by Prod type descreption doing a vlookup from the spreadsheet
ActiveSheet.Name = Application.VLookup(producttype, ThisWorkbook.Sheets("Sheet2").Range("A:B"), 2, False)
'This will paste the filtered data from Source Data to the new sheet that is added
Range("a2").Select
ActiveSheet.Paste
ns = ActiveSheet.Name
'Copeis the headers to all the new sheets
Sheets("Sheet1").Select
Range("A1:BC1").Select
Selection.Copy
Sheets(ns).Activate
Range("a1").Select
ActiveSheet.Paste
Columns.AutoFit
' Inserts a blank row for everychange in ID
myRow = 3
Do Until Cells(myRow, 3) = ""
If Cells(myRow, 3) = Cells(myRow - 1, 3) Then
myRow = myRow + 1
Else
Cells(myRow, 1).EntireRow.Insert
myRow = myRow + 2
End If
Loop
Next producttype
End Sub
Try this...
Sub runreport()
Dim rRange As Range
Dim Rng As Range
Dim FiltRows As Integer
' Open the Source File
Filename = Application.GetOpenFilename()
Workbooks.Open Filename
'Loops through each product type range from the macro spreadsheet.
For Each producttype In ThisWorkbook.Sheets("Schedule").Range("Product")
' Filters the sheet with a product code that matches and copy's the active sheet selection
Workbooks("Source.xlsx").Sheets("Sheet1").Range("A1:G1").AutoFilter Field:=4, Criteria1:=producttype
With Workbooks("Source.xlsx").Sheets("Sheet1")
FiltRows = .AutoFilter.Range.Rows.SpecialCells(xlCellTypeVisible).Count / .AutoFilter.Range.Columns.Count
End With
If FiltRows > 1 Then 'There will always be a header row which is why it needs to be greater than one.
Sheets("Sheet1").Select
Sheets("Sheet1").Select
Range("A2").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
'Adds a new workbook
ActiveWorkbook.Sheets.Add After:=ActiveWorkbook.Sheets(Sheets.Count)
'Names the worksheet by Prod type descreption doing a vlookup from the spreadsheet
ActiveSheet.Name = Application.VLookup(producttype, ThisWorkbook.Sheets("Sheet2").Range("A:B"), 2, False)
'This will paste the filtered data from Source Data to the new sheet that is added
Range("a2").Select
ActiveSheet.Paste
ns = ActiveSheet.Name
'Copeis the headers to all the new sheets
Sheets("Sheet1").Select
Range("A1:BC1").Select
Selection.Copy
Sheets(ns).Activate
Range("a1").Select
ActiveSheet.Paste
Columns.AutoFit
' Inserts a blank row for everychange in ID
myRow = 3
Do Until Cells(myRow, 3) = ""
If Cells(myRow, 3) = Cells(myRow - 1, 3) Then
myRow = myRow + 1
Else
Cells(myRow, 1).EntireRow.Insert
myRow = myRow + 2
End If
Loop
End If
Next producttype
End Sub
I would recommend you define more variables than you have it keeps the code cleaner and easier to read as well as eliminates easy errors.
I also recommend always to utilize "option explicit" at the top of every code. It forces defining all variables (when you don't define a variable the program will do it for you (assuming you haven't used option explicit), but excel doesn't always get it correct. Also option explicit helps you avoid typos in variables.
Also as a general rule you rarely if ever have to .select anything to do what you need to with vba.
Below is an example of a cleaned up and shortened code which utilized variable definition and instantiation.
Sub runreport()
Dim wb As Workbook
Dim wsSched As Worksheet
Dim wsNew As Worksheet
Dim wbSource As Workbook
Dim wsSource As Worksheet
Dim rRange As Range
Dim producttype As Range
Dim Filename As String
Dim FiltRows As Integer
Dim myRow As Integer
'instantiate Variables
Set wb = ThisWorkbook
Set wsSched = wb.Worksheets("Schedule")
' Open the Source File
Filename = Application.GetOpenFilename()
Set wbSource = Workbooks.Open(Filename)
Set wsSource = wbSource.Worksheets("Sheet1")
'Loops through each product type range from the macro spreadsheet.
For Each producttype In wsSched.Range("Product")
' Filters the sheet with a product code that matches and copy's the active sheet selection
With wsSource
.AutoFilterMode = False
.Range("A1:G1").AutoFilter Field:=4, Criteria1:=producttype
FiltRows = .AutoFilter.Range.Rows.SpecialCells(xlCellTypeVisible).Count / .AutoFilter.Range.Columns.Count
If FiltRows > 1 Then 'There will always be a header row which is why it needs to be greater than one.
'Add new workbook
Set wsNew = wb.Sheets.Add(After:=ActiveWorkbook.Sheets(Sheets.Count))
'Copy filtered data including header
.AutoFilter.Range.SpecialCells(xlCellTypeVisible).Copy
'Paste filterd data and header
wsNew.Range("A1").PasteSpecial
Application.CutCopyMode = False
wsNew.Columns.AutoFit
'Rename new worksheet
wsNew.Name = WorksheetFunction.VLookup(producttype, wb.Worksheets("Sheet2").Range("A:B"), 2, False)
' Inserts a blank row for everychange in ID
myRow = 3
Do Until Cells(myRow, 3) = ""
If Cells(myRow, 3) = Cells(myRow - 1, 3) Then
myRow = myRow + 1
Else
Cells(myRow, 1).EntireRow.Insert
myRow = myRow + 2
End If
Loop
End If
End With
Next producttype
End Sub
First, you can check this answer for ways to optimize your vba code
As for your code in its current form, it would be easiest if you select the entire range of your product code data first. Then you can check this range after your filter and determine if all the rows are hidden. See a sample of the code below
Dim productData as Range
Set productData = Range(Range("A2"), Range("A2").End(xlDown).End(xlToRight))
' Filters the sheet with a product code that matches and copy's the active sheet selection
Workbooks("Source.xlsx").Sheets("Sheet1").Range("A1:G1").AutoFilter _
Field:=4, Criteria1:=producttype
' The error check will skip the creation of a new sheet if the copy failed (i.e. returns a non-zero error number)
On Error Resume Next
' Copies only the visible cells
productData.SpecialCells(xlCellTypeVisible).Copy
If Err.number = 0 then
'Adds a new workbook
ActiveWorkbook.Sheets.Add After:=ActiveWorkbook.Sheets(Sheets.Count)
ActiveSheet.Name = Application.VLookup(producttype, _
ThisWorkbook.Sheets("Sheet2").Range("A:B"), 2, False)
Range("a2").Select
ActiveSheet.Paste
End If
While you can Range.Offset one row and check if the Range.SpecialCells method with xlCellTypeVisible is Not Nothing, I prefer to use the worksheet's SUBTOTAL function. The SUBTOTAL function discards hidden or filtered rows from its operations so a simple COUNTA (SUBTOTAL subfunction 103) of the cells below the header will tell you if there is anything available.
Sub runreport()
Dim rRange As Range, rHDR As Range, rVAL As Range, wsn As String
Dim fn As String, owb As Workbook, twb As Workbook
Dim i As Long, p As Long, pTYPEs As Variant
pTYPEs = ThisWorkbook.Sheets("Schedule").Range("Product").Value2
Set twb = ThisWorkbook
' Open the Source File
fn = Application.GetOpenFilename()
Set owb = Workbooks.Open(fn)
With owb
'is this Workbooks("Source.xlsx")?
End With
With Workbooks("Source.xlsx").Worksheets("Sheet1")
With .Cells(1, 1).CurrentRegion
'store the header in case it is needed for a new worksheet
Set rHDR = .Rows(1).Cells
'reset the the filtered cells
Set rVAL = Nothing
For p = LBound(pTYPEs) To UBound(pTYPEs)
.AutoFilter Field:=4, Criteria1:=pTYPEs(p)
With .Resize(.Rows.Count - 1, 7).Offset(1, 0) '<~~resize to A:G and move one down off the header row
If CBool(Application.Subtotal(103, .Cells)) Then
'there are visible cells; do stuff here
Set rVAL = .Cells
wsn = Application.VLookup(pTYPEs(p), twb.Worksheets("Sheet2").Range("A:B"), 2, False)
'if the wsn worksheet doesn't exist, go make one and come back
On Error GoTo bm_New_Worksheet
With Worksheets(wsn)
On Error GoTo bm_Safe_Exit
rVAL.Copy Destination:=.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
'when inserting rows, always work from the bottom to the top
For i = .Cells(Rows.Count, 3).End(xlUp).Row To 3 Step -1
If .Cells(i, 3).Value2 <> .Cells(i - 1, 3).Value2 Then
.Rows(i).Insert
End If
Next i
'autofit the columns
For i = .Columns.Count To 1 Step -1
.Columns(i).AutoFit
Next i
End With
End If
End With
Next p
End With
End With
GoTo bm_Safe_Exit
bm_New_Worksheet:
On Error GoTo 0
With Worksheets.Add(after:=Sheets(Sheets.Count))
.Name = wsn
rHDR.Copy Destination:=.Cells(1, 1)
End With
Resume
bm_Safe_Exit:
End Sub
When a worksheet that is referenced by the wsn string does not exist, the On Error GoTo bm_New_Worksheet runs off and creates one. The Resume brings the code processing right back to the place it errored out.
One caution when using this method is to ensure that you have unique, legal worksheet names returned by your VLOOKUP function.

Remove empty rows

I have an Excel macro that removes all the empty rows in an Excel sheet. This macro takes too long to finish. The files are generated automatically and every file needs to run this macro. The macro deletes one row at a time after checking its value.
I need something like this:
If rowValue = "" then
deleteThisRow And deleteAll Subsequent rows at once
End If
This is the code I am using now:
Sub RemoveRows()
Range("A8").Select
Dim checkval
Dim RowAmount
RowAmount = 93
Do
checkval = ActiveCell.Value
If (checkval = "") Then
ActiveCell.EntireRow.Delete
Else
ActiveCell.Offset(1, 0).Select
End If
RowAmount = RowAmount - 1
Loop While RowAmount > 0
End Sub
Your idea to delete all necassary rows in one operation is bang on. In addition avoiding Select and avoiding looping over a range of cells will speed thing up too.
Here's an approach that should work for you
Sub Demo()
Dim sh As Worksheet
Dim rng As Range
Dim rngBlanks As Range
' Get a reference to the sheet you want to process
Set sh = ActiveSheet
' Get a reference to the range of cells to test
With sh
Set rng = .Range(.Cells(8, 1), .Cells(.Rows.Count, 1).End(xlUp))
End With
' if there are no blanks SpecialCells will error, so handle it
On Error Resume Next
' Reduce rng to reference only blank cells
Set rngBlanks = rng.SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
' see if there are any blanks
If Not rngBlanks Is Nothing Then
' delete all of them
rngBlanks.EntireRow.Delete
End If
End Sub
Update based on additional info provided: "blank" cells may contain formulas returning an empty string.
Here's an approach using AutoFilter
Sub Demo()
Dim sh As Worksheet
Dim rng As Range
Dim rngBlanks As Range
Application.ScreenUpdating = False
' Get a reference to the sheet you want to process
Set sh = ActiveSheet
' Get a reference to the range of cells to test, plus header row
With sh
Set rng = .Range(.Cells(7, 1), .Cells(.Rows.Count, 1).End(xlUp))
End With
' Apply filr to hide non-empty cells
sh.AutoFilterMode = False
rng.AutoFilter Field:=1, Criteria1:="=", VisibleDropDown:=True
' if there are no blanks SpecialCells will error, so handle it
On Error Resume Next
' Reduce rng to reference only blank cells, exclude header row
Set rngBlanks = rng.Offset(1, 0).SpecialCells(xlCellTypeVisible)
On Error GoTo 0
' see if there are any blanks
If Not rngBlanks Is Nothing Then
' delete all of them
rngBlanks.EntireRow.Delete
End If
sh.AutoFilterMode = False
Application.ScreenUpdating = True
End Sub
So basically, if it comes across a blank row, it should delete that row and all the rows below it.
For deleting all the rows below, you could essentially do the same thing that happens when you press CTRL and the down arrow - it goes to either the next value down (if there is one, and in your case it sounds like there won't be) or to the end (row 65536 is the limit in all the Excel versions I've come across). Which would be...
Range(Selection, Selection.End(xlDown)).Select
Selection.Delete Shift:=xlUp
This will go from the row you've selected (so no need to delete it), down to either the next value or the end, and delete all those rows.
EDIT - entire macro:
Dim i As Integer
For i = 1 To 93
Range("A" & i).Select
Dim CheckVal As String
CheckVal = ActiveCell.Value
If (CheckVal = "") Then
Range(Selection, Selection.End(xlDown)).Select
Selection.Delete Shift:=xlUp
End If
Next i
Bear in mind though that, if there ARE any values below the first "blank" that is found, they are deleted too as the first contiguous value.

Copy data from a Subset of Worksheets in a workbook and pasting to a master worksheet, disregarding the standard mastersheets

Hello to the community and thank you in advance for your assistance. I have created a workbook that has a variable number of worksheets most of which have variable name. There are however, 4 worksheets that will not change and I do not want data copied from them. The code I am attempting is below: If I am way off base, please let me know.
V/R
Doug
Private Sub GroupReport_Click()
Dim sh As Worksheet
Dim DestSh As Worksheet
Dim Last As Long
Dim CopyRng As Range
Dim Disreguard(1 To 4) As String
Disreguard(1) = "RDBMergeSheet"
Disreguard(2) = "0 Lists"
Disreguard(3) = "0 MasterCrewSheet"
Disreguard(4) = "00 Overview"
' Delete the summary sheet if it exists.
Application.DisplayAlerts = False
On Error Resume Next
ActiveWorkbook.Worksheets("RDBMergeSheet").Delete
On Error GoTo 0
Application.DisplayAlerts = True
' Add a new summary worksheet.
Set DestSh = ActiveWorkbook.Worksheets.Add
DestSh.Name = "RDBMergeSheet"
' Loop through all worksheets and copy the data to the
' summary worksheet.
For Each sh In ActiveWorkbook.Worksheets
If sh.Name <> Disreguard.Worksheets.Name Then
Last = LastRow(DestSh)
Set CopyRng = sh.Rows("21")
CopyRng.Copy
With DestSh.Cells(Last + 1, "A")
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
End With
End If
Next
Unfortunately, this line will not work for you:
If sh.Name <> Disreguard.Worksheets.Name Then
The Disreguard variable is an array, but not an object in VBA, so there are no methods you can access with the dot operator. You would have to loop through the array's contents and check each item against the string you're testing.
You can add a function to test it like this:
Private Function toDisreguard(ByRef list() as String, ByRef searchString As String) As Boolean
Dim i As Long
For i = LBound(list) To UBound(list)
If (searchString = list(i)) Then
toDisreguard = True
Exit Function
End If
Next i
toDisreguard = False
End Function
And then pass the array along with the sheet name to test like so:
If (toDisreguard(Disreguard, sh.Name) = False) Then
Also, the LastRow() function is not defined from what you posted. Is this a function you created?
In fact, you could just keep track of the last row yourself since you're rebuilding the "RDBMergeSheet" worksheet each time you run this. You can start by setting Last = 1 and then increment along the way. And one last thing, you should probably test to see if there is any data in row 21 for each sheet so you're not copying a blank row:
' Loop through all worksheets and copy the data to the
' summary worksheet.
Last = 1
For Each sh In ActiveWorkbook.Worksheets
If (toDisreguard(Disreguard, sh.Name) = False) Then
'Last = LastRow(DestSh)
If (Application.WorksheetFunction.CountA(sh.Rows("21")) > 0) Then
Set CopyRng = sh.Rows("21")
CopyRng.Copy
With DestSh.Cells(Last, "A") ' notice i changed this as well
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
End With
Last = Last + 1
End If
End If
Next

Excel 2007, Copying rows from one sheet to another based on a value in 1 column

I'm trying to copy a range of rows where the rows chosen are based on the value in one cell.I want to do this for all rows containing the same value in a cell, then move on to the next value an append to the bottom of the first list.
Below is my attempt at explaining what I wish to achieve - hopefully the above will help explain more my dilemma. I have looked around for this but not quite found what I want. I thought it would be simple and probably is.
I receive a data dump with thousands of rows of data and 18 columns. Based on the value of column P "Contract" I want to copy entire rows into a new single worksheet workingdata. Not all the data will go into the workingdata worksheet.
The contract numbers are c1234, c1235, c2345 etc.
What i am after achieving is copying and sorting, so copy all the rows of data where contract number is c1234, in workingdata, then directly below it copy all rows where contract is c1235 and so on.
I thought I could select the range P:P and sort but to no avail.
Sheets("Data Dump").Select
Columns("P:P").Select
If Selection.Value = "C1234" Then
Selection.EntireRow.copy
I know I should post what i have tried, but it would be a pathetic, for some reason I just can't seem to get my head round this one.
Here's my latest effort - I know there are errors
Dim oWorksheet As Excel.Worksheet
Dim oRangeSource As Excel.Range
Dim oRangeDest As Excel.Range
Set oWorksheet = Worksheets("DataDump")
Set oRangeSource = oWorksheet.Range("p:p")
Set oRangeDest = Worksheets("workingdata")
If oRangeSource="CA0004000" Then Select.EntireRow
Selection.EntireRow.copy
Sheets("workingdata").Select.Paste
End If
latest effort but does not sort data or get rid of unwanted, I have to do a manual filter and sort which sorts of defeats the object of the macro
Sub copy()
'
' copy Macro
'
Dim rngContracts As Range: Set rngContracts = Sheets("DataDump").Range("P:P")
Dim wsData As Worksheet
Dim wsFound As Boolean: wsFound = False
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If ws.Name = "Working Data" Then
Set wsData = ws
wsFound = True
Exit For
End If
Next ws
If wsFound = False Then
Application.CutCopyMode = False
ActiveSheet.Range("A1").EntireRow.copy
Set wsData = Sheets.Add(After:=Sheets(Sheets.Count))
wsData.Name = "Working Data"
wsData.Range("A1").EntireRow.PasteSpecial xlPasteAll, Transpose:=False
End If
Dim iCell As Range
For Each iCell In rngContracts
If iCell.EntireRow.Hidden = False Then
Application.CutCopyMode = False
iCell.EntireRow.copy
wsData.Range("P" & Rows.Count).End(xlUp).Offset(1, 0).EntireRow.PasteSpecial xlPasteAll, Transpose:=False
End If
Next iCell
Application.CutCopyMode = False
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Latest attaempt - copies the data I need but does not sort:
Sub copytest()
'
' copytest Macro
'
Set MR = Sheets("data Dump").Range("P:P")
For Each cell In MR
If cell.Value = "CA000154" Then
cell.EntireRow.copy
Sheets("working data").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial
End If
If cell.Value = "CA000220" Then
cell.EntireRow.copy
Sheets("working data").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial
End If
If cell.Value = "CA000393" Then
cell.EntireRow.copy
Sheets("working data").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial
End If
If cell.Value = "CA000429" Then
cell.EntireRow.copy
Sheets("working data").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial
End If
Application.CutCopyMode = False
Next
End Sub
Record a macro to set filters on your data select one filter only.
Then, edit the code and loop through each filter copying the visible range on to your sheet. This must also sort your data as the filters are already sorted.
Also, take a look at creating filter arrays in the Excel VBA help with regards to using them to sort.

Resources