I'm setting up a workbook that has two sheets. One sheet is for a data set and the second sheet is for analysis.
The data set sheet will be first (on the left/Sheet1) followed by the analysis sheet second (on the right/Sheet2).
Each sheet Name will have today's date and a title.
I would like to check if both sheets are present for today's date.
If Sheet1 is missing, add on the left.
If Sheet2 is missing, add on the right.
If both are missing, add both.
There should be no other sheets.
I have two modules. One checks for one sheet, and one checks for the other.
Option Explicit
Public szTodayRtsMU As String
Dim szTodayRawData As String
' Add and name a sheet with today's date.
Sub AddRtsMUsSheets_Today()
' Date and title.
szTodayRtsMU = Format(Date, "dd-mm-yyyy") & " " & "Rts & MUs"
On Error GoTo MakeSheet
' Check if sheet already exists, if it does, select activate it.
Sheets(szTodayRtsMU).Activate
' No errors, code is done.
Exit Sub
MakeSheet:
' If the sheet doesn't exist, add it.
ActiveWorkbook.Sheets.Add After:=Worksheets(Worksheets.Count)
' Name it
ActiveSheet.Name = szTodayRtsMU
End Sub
Sub AddRawDataSheets_Today()
' Date and title.
szTodayRawData = Format(Date, "dd-mm-yyyy") & " " & "Raw Data"
On Error GoTo MakeSheet
' Check if sheet already exists, if it does, select activate it.
Sheets(szTodayRawData).Activate
' No errors, code is done.
Exit Sub
MakeSheet:
' If the sheet doesn't exist, add it.
ActiveWorkbook.Sheets.Add Before:=Worksheets(Worksheets.Count)
' Name it
ActiveSheet.Name = szTodayRawData
End Sub
Tested, 100% working:
Option Explicit
Sub CheckForWorksheets()
Dim szTodayRawData As String
Dim szTodayRtsMU As String
Dim ws As Worksheet
Dim countRawData As Byte 'check if exists the RawData sheet
Dim countRTsMU As Byte 'check if exists the RtsMU sheet
'Date and titles
szTodayRawData = Format(Date, "dd-mm-yyyy") & " " & "Raw Data"
szTodayRtsMU = Format(Date, "dd-mm-yyyy") & " " & "Rts & MUs"
'Initialize the counters with 1
countRawData = 1
countRTsMU = 1
'This is a loop on all the worksheets on this workbook
For Each ws In ThisWorkbook.Worksheets
'If the sheets exists then the counter goes to 0
If ws.Name = szTodayRawData Then
countRawData = 0
ElseIf ws.Name = szTodayRtsMU Then
countRTsMU = 0
End If
Next ws
'Add the sheets if needed
With ThisWorkbook
If countRawData = 1 Then
Set ws = .Sheets.Add(before:=.Sheets(.Sheets.Count))
ws.Name = szTodayRawData
End If
If countRTsMU = 1 Then
Set ws = .Sheets.Add(After:=.Sheets(.Sheets.Count))
ws.Name = szTodayRtsMU
End If
End With
'Delete any other sheet
For Each ws In ThisWorkbook.Sheets
If Not ws.Name = szTodayRawData And Not ws.Name = szTodayRtsMU Then
Application.DisplayAlerts = False
ws.Delete
Application.DisplayAlerts = True
End If
Next ws
End Sub
If you need help understanding the code ask me anything.
Related
I have the following code that produces a new worksheet. I'm trying to name the new worksheet using a Phrase, the content in Cell 1, and the date in Cell 2.
Cell 1 will contain some data that are inserted via Data Validation (4 options in total) and Cell 2 will have a date.
EXAMPLE:
Worksheet INPUTS Range C3. Cell 1 value = Trade Activities, Purchases, Sales...etc
Worksheet INPUTS Range C2. Cell 2 value = 2.11.2020
The new workbook's name will be "Client Name Trade Activities - 2.11.2020"
both Cell 1 and Cell 2 will be in the INPUTS worksheet
Private Sub CommandButton1_Click()
Dim targetWorkbook As Workbook
Dim sourceSheet As Worksheet
Dim formatDate As String
Dim fileName As String
Set sourceSheet = ThisWorkbook.Worksheets("Sheet1")
If sourceSheet.AutoFilterMode Then sourceSheet.AutoFilterMode = False
If ThisWorkbook.Worksheets("INPUTS").Range("C3").Value <> vbNullString Then
formatDate = Format(Sheets("INPUTS").Range("C3"), "YYYY.MM.DD")
End If
fileName = "Name - " & ActivityName & formatDate
sourceSheet.Outline.ShowLevels ColumnLevels:=1
sourceSheet.Range("A:M").AutoFilter Field:=12, Criteria1:="<>0"
Set targetWorkbook = Workbooks.Add
sourceSheet.UsedRange.SpecialCells(xlCellTypeVisible).Copy targetWorkbook.Worksheets(targetWorkbook.Sheets.Count).Range("A1")
targetWorkbook.Sheets("sheet1").Columns("A:AC").EntireColumn.AutoFit
targetWorkbook.SaveAs ThisWorkbook.Path & "\" & fileName & ".xlsx", FileFormat:=51
End Sub
Some things to remember:
Define and reuse your variables whenever you can
Try to add comments to your code, explaining the purpose of what you're doing (your future self or whom ever is going to work with your files, is going to thank you)
Leave spaces between your code's main parts, so it's more readable
EDIT: Added error handler, for when user clicks "No" when asking to overwrite existing file
Code:
Private Sub CommandButton1_Click()
Dim targetWorkbook As Workbook
Dim sourceSheet As Worksheet
Dim formatDate As String
Dim fileName As String
On Error GoTo CleanFail
Set sourceSheet = ThisWorkbook.Worksheets("Sheet1")
' Remove filter
If sourceSheet.AutoFilterMode Then sourceSheet.AutoFilterMode = False
If sourceSheet.Range("F1").Value <> vbNullString Then
formatDate = Format(sourceSheet.Range("F1").Value, "YYYY.MM.DD")
End If
' Set the new workbook file name
fileName = "NAME - " & formatDate
' Filter the fileNames
sourceSheet.Range("A:C").AutoFilter Field:=2, Criteria1:="<>"
' Add new workbook and set reference
Set targetWorkbook = Workbooks.Add
' Copy the visible fileNames in a new workbook
sourceSheet.UsedRange.SpecialCells(xlCellTypeVisible).Copy targetWorkbook.Worksheets(targetWorkbook.Sheets.Count).Range("A1")
' Save the new workbook
targetWorkbook.SaveAs ThisWorkbook.Path & "\" & fileName & ".csv", FileFormat:=xlCSV
CleanExit:
Exit Sub
CleanFail:
Select Case Err.Number
Case 1004
MsgBox "You cancel the process"
Resume Next
Case Else
' Do something else? handle it properly...
MsgBox "Something went wrong..."
Resume CleanExit
End Select
End Sub
Let me know if it works
The goal is to create a copied sheet that is renamed in the current month and year. The copied sheet is being created in the workbook, however a default name is given to the sheet. What am I missing?
Private Sub Button3_Click()
Dim wb As Workbook
Dim ws As Worksheet
Dim nowMonth As Integer, nowYear As Integer
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
nowMonth = Month(Now)
nowYear = Year(Now)
Set wb = ActiveWorkbook
On Error Resume Next
Set ws = wb.Sheet(nowMonth & ", " & nowYear)
On Error GoTo 0
If Not ws Is Nothing Then
MsgBox "The Sheet called " & nowMonth & ", " & nowYear & " already exists in the workbook.", vbExclamation, "Sheet Already Exists!"
Exit Sub
Else
Set ws = ActiveSheet.Copy(after:=wb.Sheets(wb.Sheets.Count))
ws.Name = nowMonth & ", " & nowYear
End If
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
The problem is in Set ws = ActiveSheet.Copy(after:=wb.Sheets(wb.Sheets.Count)), because it is trying to Copy and Set in the same time and this is a bit too much.
Change the code in the condition to this:
If Not ws Is Nothing Then
MsgBox "something"
Exit Sub
Else:
Set ws = ActiveSheet
ws.Copy after:=wb.Sheets(wb.Sheets.Count)
wb.Worksheets(wb.Sheets.Count).Name = nowMonth & ", " & nowYear
End If
In general, avoid using Active and Select in VBA - How to avoid using Select in Excel VBA.
Worksheet.Copy disappointingly doesn't return a reference to the created sheet. Instead, it has the side-effect of adding a new sheet to the workbook, and activating it.
So after running Worksheet.Copy, the ActiveSheet is the newly created sheet.
ActiveSheet.Copy after:=wb.Sheets(wb.Sheets.Count)
ActiveSheet.Name = nowMonth & ", " & nowYear
Now, this code is confusing/misleading, because it looks like the two statements are qualified with the same object, but they aren't.
What's not clear, is why and how the ActiveSheet is guaranteed to be the correct sheet to copy; we're working off the ActiveWorkbook and we don't really care which sheet is active.
I'd suggest to make the copy work off an explicit sheet:
Dim sourceSheet As Worksheet
Set sourceSheet = wb.Sheets(wb.Sheets.Count)
sourceSheet.Copy after:=sourceSheet '<~ new sheet becomes ActiveSheet
ActiveSheet.Name = nowMonth & ", " & nowYear
And now everything is as clear as it gets.
I have a workbook with many sheets. I am webscraping with numbers, and then making each sheet have the number as the name. I want to display an error if the number has already been given to a sheet. I also want the user to be able to enter a new sheetname if so, but the program keeps popping up its own error message before I can do this.
The number is in cell D10 in the worksheet.
For Each Sheet In ThisWorkbook.Sheets
If Sheet.Name = Range("D10") Then
MsgBox ("ERROR: This Acct No has already been formulated")
NewName = InputBox("Please Rename:")
ActiveSheet.Name = NewName
ElseIf Sheet.Name <> Range("D10") Then
ActiveSheet.Name = Range("D10")
End If
Next Sheet
I expect my own message to pop up, but Excel just pops its own error message.
try this:
Dim MyDuplicate as boolean
MyDuplicate = False
For Each Sheet In ThisWorkbook.Sheets
If Sheet.Name = Range("D10") Then
MsgBox ("ERROR: This Acct No has already been formulated")
NewName = InputBox("Please Rename:")
ActiveSheet.Name = NewName
MyDuplicate = True
Exit for
End If
Next Sheet
If MyDuplicate = False then ActiveSheet.Name = Range("D10")
BTW, I do recommend you avoid using ActiveSheet and assign the sheet to a variable instead.
Option Explicit
Sub TestMe()
Dim wks As Worksheet
Worksheets.Add After:=ActiveSheet
For Each wks In ThisWorkbook.Worksheets
With wks
If .Name = .Range("D10") Then
MsgBox ("ERROR: This Acct No has already been formulated")
.Name = InputBox("Please Rename:")
ElseIf .Name <> .Range("D10") Then
If Trim(.Range("D10")) = "" Then
.Range("D10") = Replace(Replace(Now, ":", "_"), "/", "_")
Application.Wait Now + #12:00:02 AM#
End If
.Name = .Range("D10").Value
End If
End With
Next wks
End Sub
This is some idea how to do it, avoiding the Activate and Select, as per the How to avoid using Select in Excel VBA
(Ironically, I have left Worksheets.Add After:=ActiveSheet)
The part .Range("D10") = Replace(Replace(Now, ":", "_"), "/", "_") writes the current date and time, making sure it is always a unique one, by waiting 2 seconds on the next line - Application.Wait Now + #12:00:02 AM#
Rather than looping every sheet to check for duplicates, create a function that returns a boolean. This function will have an error if the sheet doesn't exist, and no error if the sheet does exist. We check for that error, and return True if sheet exists, False otherwise.
Option Explicit
Private Function SheetExists(wsName As String, Optional wb As Workbook = Nothing) As Boolean
Dim ws As Worksheet
On Error Resume Next
If wb Is Nothing Then
Set ws = Worksheets(wsName)
Else
Set ws = wb.Worksheets(wsName)
End If
SheetExists = (Err.Number = 0)
End Function
And then your code could be replaced with the following, which will keep calling on the InputBox as many times as necessary in order to prevent the user from inputting another invalid/duplicate entry. For this, I've combined the MsgBox and InputBox text, seems unnecessary to throw two prompts at the user when we can use the InputBox to both inform and ask for new input.
Dim ws as Worksheet
Dim newName as String
Set ws = ActiveSheet ' would be better to avoid this, but OK.
newName = Range("D10").Value
While SheetExists(newName, ws.Parent)
newName = InputBox("ERROR: This Acct No has already been formulated!" & vbCrLf & vbCrLf & _
newName & " already exists! Enter new name:")
Wend
ws.Name = newName
I have an Excel VBA file with the following code. My issue is that the InputBox doesn't work correctly. There are 10 sheets. The first sheet is called "Menu". Other sheets as Sheet 2 - 10. Sheet 3,4 & 5 applied VeryHidden. Please help me to rectify it.
Private Sub CommandButton1_Click()
Dim Sh As Worksheet
For Each Sh In ThisWorkbook.Worksheets
If Sh.Name <> "Menu" Then
Sheet3.Visible = xlSheetVeryHidden
Sheet4.Visible = xlSheetVeryHidden
Sheet5.Visible = xlSheetVeryHidden
End If
Next Sh
Dim myList As String
Dim i As Integer
Dim mySht
i = 1
For Each oSheet In ActiveWorkbook.Sheets
If oSheet.Visible <> xlSheetVeryHidden Then
myList = myList & i & " - " & oSheet.Name & " " & vbCr
i = i + 1
End If
Next oSheet
mySht = InputBox("Select Sheet to go to." & vbCr & myList)
ActiveWorkbook.Sheets(CInt(mySht)).Select
End Sub
Like I said in my comment above; The problem is Sheets(CInt(mySht)).
Problem
When you specify a number, say 3, then the code Sheets(CInt(mySht)) becomes Sheets(3). But this is not what you want. You want the name after that number as you are concatenating that number with " - " and then with the sheet name. Sheets(3) actually may be referring to the hidden sheet and not the 3rd Visible sheet and hence you are getting the error.
Option
Instead of using myList, use an array.
Split the array after the user makes a choice and then go to that sheet
Solution
Is this what you are trying?
Private Sub CommandButton1_Click()
Dim Sh As Worksheet
Dim ShName As String
Dim i As Integer
Dim mySht, MyAr
For Each Sh In ThisWorkbook.Worksheets
Sh.Visible = xlSheetVisible
Next Sh
Sheet3.Visible = xlSheetVeryHidden
Sheet4.Visible = xlSheetVeryHidden
Sheet5.Visible = xlSheetVeryHidden
For Each Sh In ThisWorkbook.Worksheets
If Sh.Visible = xlSheetVeryHidden Then i = i + 1
Next Sh
ReDim MyAr(1 To ThisWorkbook.Sheets.Count - i)
i = 1
'~~> Store the names of all visible sheets in the array
For Each Sh In ActiveWorkbook.Sheets
If Sh.Visible = xlSheetVisible Then
MyAr(i) = i & " - " & Sh.Name
i = i + 1
End If
Next Sh
'~~> Get user input
mySht = InputBox("Select Sheet to go to." & vbCr & Join(MyAr, vbNewLine))
If IsNumeric(mySht) Then
'~~> Get the actual sheet name using split as
'~~> we had actually appended " - " to it earlier
ShName = Trim(Split(MyAr(mySht), " - ")(1))
'~~> Activate the sheet
ThisWorkbook.Sheets(ShName).Activate
End If
End Sub
I have a template file which will be sent out to all subsidiaries of my company.
The template has a tab named start and one named end.
The subsidiaries will place a variable number of template submission sheets between these two names sheets and send them in to me to consolidate into one sheet in my consolidation file.
I have written macros to copy each sheet into the consolidation file, but I currently need to run it sheet by sheet as I don't know how to loop.
The copy macro sits in my Personal.xls file and the paste macro sits in the consolidation sheet.
The loop macro would need to work between the Source file (could be any name) and the consolidation file which is called Consolidation.xls.
Once all sheets are copied from a source file, I then open the next source file and start again, so macro would need to forget the old source file and remember the new one.
This could literally save me hours each week if I could get a macro to work, so any help much appreciated.
I think this is along the lines of what you are chasing. If all your templates are in a single folder, and each have a "start" and "end" sheet then this code will collate them into either
A new workbook with a unique sheet for each relevant sheet in each template
Into a single sheet in a new workbook
I have updated my code from "Collating worksheets from one or more workbooks into a summary file", http://www.experts-exchange.com/A_2804.html to cater for your "start" and "end" sheets
Please post if you need (or have) further detail
Public Sub ConsolidateSheets()
Dim Wb1 As Workbook
Dim Wb2 As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim ws3 As Worksheet
Dim rng1 As Range
Dim rng2 As Range
Dim rng3 As Range
Dim rngArea As Range
Dim lrowSpace As Long
Dim lSht As Long
Dim lngCalc As Long
Dim lngRow As Long
Dim lngCol As Long
Dim X()
Dim bProcessFolder As Boolean
Dim bNewSheet As Boolean
Dim StrPrefix
Dim strFileName As String
Dim strFolderName As String
'variant declaration needed for the Shell object to use a default directory
Dim strDefaultFolder As Variant
bProcessFolder = (MsgBox("Process a single folder (Yes)," & vbNewLine & "or single file (No)", vbYesNo, "Application Scope: Folder or single File") = vbYes)
bNewSheet = (MsgBox("Extract all data to a single sheet (Yes)," & vbNewLine & "or a target file sheet for each source sheet (No)", vbYesNo, "Output Format: Single sheet or sheet by sheet collection") = vbYes)
If Not bProcessFolder Then
If Not bNewSheet Then
MsgBox "There isn't much point creating a exact replica of your source file :)"
Exit Sub
End If
End If
'set default directory here if needed
strDefaultFolder = "C:\"
'If the user is collating all the sheets to a single target sheet then the row spacing
'to distinguish between different sheets can be set here
lrowSpace = 1
If bProcessFolder Then
strFolderName = BrowseForFolder(strDefaultFolder)
'Look for xls, xlsx, xlsm files
strFileName = Dir(strFolderName & "\*.xls*")
Else
strFileName = Application _
.GetOpenFilename("Select file to process (*.xls*), *.xls*")
End If
Set Wb1 = Workbooks.Add(1)
Set ws1 = Wb1.Sheets(1)
If Not bNewSheet Then ws1.Range("A1:B1") = Array("workbook name", "worksheet count")
'Turn off screenupdating, events, alerts and set calculation to manual
With Application
.DisplayAlerts = False
.EnableEvents = False
.ScreenUpdating = False
lngCalc = .Calculation
.Calculation = xlCalculationManual
End With
'set path outside the loop
StrPrefix = strFolderName & IIf(bProcessFolder, "\", vbNullString)
Do While Len(strFileName) > 0
'Provide progress status to user
Application.StatusBar = Left("Processing " & strFolderName & "\" & strFileName, 255)
'Open each workbook in the folder of interest
Set Wb2 = Workbooks.Open(StrPrefix & strFileName)
If Not bNewSheet Then
'add summary details to first sheet
ws1.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0) = Wb2.Name
ws1.Cells(Rows.Count, "A").End(xlUp).Offset(0, 1) = Wb2.Sheets.Count
End If
For Each ws2 In Wb2.Sheets
If ws2.Index > Wb2.Sheets("start").Index And ws2.Index < Wb2.Sheets("end").Index Then
If bNewSheet Then
'All data to a single sheet
'Skip importing target sheet data if the source sheet is blank
Set rng2 = ws2.Cells.Find("*", ws2.[a1], xlValues, , xlByRows, xlPrevious)
If Not rng2 Is Nothing Then
Set rng1 = ws1.Cells.Find("*", ws1.[a1], xlValues, , xlByRows, xlPrevious)
'Find the first blank row on the target sheet
If Not rng1 Is Nothing Then
Set rng3 = ws2.Range(ws2.UsedRange.Cells(1), ws2.Cells(rng2.Row, "A"))
'Ensure that the row area in the target sheet won't be exceeded
If rng3.Rows.Count + rng1.Row < Rows.Count Then
'Copy the data from the used range of each source sheet to the first blank row
'of the target sheet, using the starting column address from the source sheet being copied
ws2.UsedRange.Copy ws1.Cells(rng1.Row + 1 + lrowSpace, ws2.UsedRange.Cells(1).Column)
Else
MsgBox "Summary sheet size exceeded. Process stopped on " & vbNewLine & _
"sheet: " & ws2.Name & vbNewLine & "of" & vbNewLine & "workbook: " & Wb2.Name
Wb2.Close False
Exit Do
End If
'colour the first of any spacer rows
If lrowSpace <> 0 Then ws1.Rows(rng1.Row + 1).Interior.Color = vbGreen
Else
'target sheet is empty so copy to first row
ws2.UsedRange.Copy ws1.Cells(1, ws2.UsedRange.Cells(1).Column)
End If
End If
Else
'new target sheet for each source sheet
ws2.Copy after:=Wb1.Sheets(Wb1.Sheets.Count)
'Remove any links in our target sheet
With Wb1.Sheets(Wb1.Sheets.Count).Cells
.Copy
.PasteSpecial xlPasteValues
End With
On Error Resume Next
Wb1.Sheets(Wb1.Sheets.Count).Name = ws2.Name
'sheet name already exists in target workbook
If Err.Number <> 0 Then
'Add a number to the sheet name till a unique name is derived
Do
lSht = lSht + 1
Set ws3 = Wb1.Sheets(ws2.Name & " " & lSht)
Loop While Not ws3 Is Nothing
lSht = 0
End If
On Error GoTo 0
End If
End If
Next ws2
'Close the opened workbook
Wb2.Close False
'Check whether to force a DO loop exit if processing a single file
If bProcessFolder = False Then Exit Do
strFileName = Dir
Loop
'Remove any links if the user has used a target sheet
If bNewSheet Then
With ws1.UsedRange
.Copy
.Cells(1).PasteSpecial xlPasteValues
.Cells(1).Activate
End With
Else
'Format the summary sheet if the user has created separate target sheets
ws1.Activate
ws1.Range("A1:B1").Font.Bold = True
ws1.Columns.AutoFit
End If
With Application
.CutCopyMode = False
.DisplayAlerts = True
.EnableEvents = True
.ScreenUpdating = True
.Calculation = lngCalc
.StatusBar = vbNullString
End With
End Sub
Function BrowseForFolder(Optional OpenAt As Variant) As Variant
'From Ken Puls as used in his vbaexpress.com article
'http://www.vbaexpress.com/kb/getarticle.php?kb_id=284
Dim ShellApp As Object
'Create a file browser window at the default folder
Set ShellApp = CreateObject("Shell.Application"). _
BrowseForFolder(0, "Please choose a folder", 0, OpenAt)
'Set the folder to that selected. (On error in case cancelled)
On Error Resume Next
BrowseForFolder = ShellApp.self.Path
On Error GoTo 0
'Destroy the Shell Application
Set ShellApp = Nothing
'Check for invalid or non-entries and send to the Invalid error
'handler if found
'Valid selections can begin L: (where L is a letter) or
'\\ (as in \\servername\sharename. All others are invalid
Select Case Mid(BrowseForFolder, 2, 1)
Case Is = ":"
If Left(BrowseForFolder, 1) = ":" Then GoTo Invalid
Case Is = "\"
If Not Left(BrowseForFolder, 1) = "\" Then GoTo Invalid
Case Else
GoTo Invalid
End Select
Exit Function
Invalid:
'If it was determined that the selection was invalid, set to False
BrowseForFolder = False
End Function
You should show us some code if you really want help.
But as far as I understood your question, here are some tips or links.
Code snippet to loop over worksheets
Dim wkbkorigin As Workbook
Dim ws As Worksheet
Set wkbkorigin = Workbooks.Open("C:\bookB.xls")
For Each ws In wkbkorigin.Worksheets
'do whatever
Next
Some stackoverflow threads about this issue
excel vba loop through worksheets and set values according to input
How can I loop through a subset of worksheets?
Some more tips about getting info from files
See this valuable thread: Copy data from another Workbook through VBA
You will find info about:
how to use the Excel object model to copy data from a file to another
using GetInfoFromClosedFile() function
Once you've defined workbooks/worksheets as per JMax response, I think you're looking for the following...
IncludeSheet=0
For n = 1 to wkbkOrigin.Worksheets.Count
If wkbkOrigin.Sheets(n).Name = "End" Then
IncludeSheet = 0
End If
If IncludeSheet = 1 Then
Set ws = wkbkOrigin.Sheets(n)
'do whatever
End If
If wkbkOrigin.Sheets(n).Name = "Start" Then
IncludeSheet = 1
End If
Next n
The key is to introduce a flag variable to tell you if you're in the right part of the workbook, in this case IncludeSheet