7

I know how to loop through all the worksheets in a workbook, and how to exit once I reach an 'end-flag' worksheet:

For Each ThisWorkSheet In Worksheets
   If ThisWorkSheet.Name = "FlagEnd" Then Exit For
   MsgBox "This worksheet name is: " & ThisWorkSheet.Name
Next

However I cannot get the loop to begin on a 'start-flag' worksheet (or even better on the worksheet right after the start-flag worksheet. For example the flagged start/end worksheets are in the middle of a bunch of other worksheets, so beginning or end traversing is not workable.

There could be hundreds of worksheets before that 'FlagStart' sheet, so I really need to start on the right sheet.

Tried:

Set ThisWorkSheet = Sheets("FlagNew")

and

For Each Sheets("FlagNew") In Worksheets

Ideas?

Solution: Mathias was very close, but dendarii was that tiny step closer with the custom ending index. I actually figured out my final solution on my own, but wanted to give credit. Here was my final solution:

Private Sub CommandButtonLoopThruFlaggedSheets_Click()
    ' determine current bounds
    Dim StartIndex, EndIndex, LoopIndex As Integer
    StartIndex = Sheets("FlagNew").Index + 1
    EndIndex = Sheets("FlagEnd").Index - 1

    For LoopIndex = StartIndex To EndIndex
        MsgBox "this worksheet is: " & Sheets(LoopIndex).Name
        ' code here
    Next LoopIndex
End Sub
Community
  • 1
  • 1
Stay-at-home-dad
  • 876
  • 3
  • 12
  • 27
  • 3
    Kirk, you may not be aware of this, but if you declare 3 variables on the same line with one type at the end, only the last variable actually takes that type, the others end up as variants. If you're going to have all your declarations on one line, you need to specify "Dim StartIndex as Integer, EndIndex as Integer, LoopIndex as Integer". – dendarii Oct 21 '09 at 08:14
  • Doh, burned myself with shortcuts again! Thanks I was not aware of that, I will change it. – Stay-at-home-dad Oct 22 '09 at 15:35

6 Answers6

2

I believe that if you use "foreach" you won't have any control over the starting sheet. For that matter, I am not even sure you are guaranteed the order in which the iteration will take place.
I think what you should do is first, get the index of the sheet you are interested in (get the sheet by name, and get its index), and then iterate using a for loop, over the indexes of the sheets starting at the flag sheet index.
[Edit: I hacked through a quick example]

Sub Iterate()

Dim book As Workbook
Dim flagIndex As Integer
Dim flagSheet As Worksheet

Set book = ActiveWorkbook
Set flagSheet = book.Worksheets("Sheet3")
flagIndex = flagSheet.Index

Dim sheetIndex As Integer
Dim currentSheet As Worksheet

For sheetIndex = flagIndex To book.Worksheets.Count
    Set currentSheet = book.Worksheets(sheetIndex)
Next

End Sub
Mathias
  • 15,191
  • 9
  • 60
  • 92
2

If this is not a particularly changeable workbook (i.e. worksheets are not being added and deleted all the time), you could store the names of the worksheets in a range on a hidden sheet and loop through them by name.

However, it sounds like they are stored consecutively in the workbook so, building on Mathias' solution, you could use a function to return the indices of the start and end worksheets and then loop through:

Public Function GetStartIndex() As Integer
    On Error Resume Next
    GetStartIndex = ThisWorkbook.Worksheets("MyStartingWorksheet").Index + 1
End Function

Public Function GetEndIndex() As Integer
    On Error Resume Next
    GetEndIndex = ThisWorkbook.Worksheets("MyEndingWorksheet").Index - 1
End Function

Sub LoopThrough()

    Dim wks As Worksheet
    Dim i As Integer
    Dim iStart As Integer
    Dim iEnd As Integer

    iStart = GetStartIndex()
    iEnd = GetEndIndex()

    If iStart > 0 And iEnd > 0 And iEnd > iStart Then
        For i = iStart To iEnd
            Set wks = ThisWorkbook.Worksheets(i)
            MsgBox wks.Name
        Next i
    End If

End Sub
dendarii
  • 2,958
  • 20
  • 15
  • Mathias was very close, but this was that tiny step closer with the custom ending index. I actually figured out my final solution on my own, but wanted to give credit here. Private Sub CommandButtonLoopThruFlaggedSheets_Click() ' determine current bounds Dim StartIndex, EndIndex, LoopIndex As Integer StartIndex = Sheets("FlagNew").Index + 1 EndIndex = Sheets("FlagEnd").Index - 1 For LoopIndex = StartIndex To EndIndex MsgBox "this worksheet is: " & Sheets(LoopIndex).Name ' code here Next LoopIndex End Sub – Stay-at-home-dad Oct 20 '09 at 21:40
  • (solution edited into original question above with code formatting) – Stay-at-home-dad Oct 20 '09 at 21:42
  • I see that you have set up a good function. I'd like to suggest a few things though. I suggest you take the name of the sheet for which you want to find the index, as an argument in the function. By taking no arguments, you've made the function static; you might as well have written those two lines in your main sub. Then, use the sheets collection to get the index, because, the code may not work as you expect it to, when the workbook has chart sheets. – Ejaz Ahmed Sep 11 '15 at 06:52
1

How about?

For Each ThisWorkSheet In Worksheets  
    If ThisWorkSheet.Name = "FlagStart" Then output = true 
    If ThisWorkSheet.Name = "FlagEnd" Then Exit For   
    If output = true Then MsgBox "This worksheet name is: " & ThisWorkSheet.Name
Next

This code might not be quite right. I'm writing it in the SO editor not VBA, but you get the idea.

Ade Miller
  • 13,575
  • 1
  • 42
  • 75
  • 1
    I should have mentioned I thought of that, but it's not efficient enough. There could be hundreds of worksheets in front of the FlagStart worksheet. I would really rather start right at the correct worksheet. Thanks though! – Stay-at-home-dad Oct 19 '09 at 22:36
  • @Kirk Hings - premature optimization will bite you! I'd suggest getting a working solution first, then look at ways to optimize it. Also I would be worried having hundreds of sheets. Is Excel the best tool? – Christian Payne Oct 20 '09 at 01:22
  • good points, i actually am optimizing the solution that they are already using. currently they copy paste a bunch of this stuff and we are trying to automate it for them. i guess i exaggerated at hundreds, but there can be dozens of sheets, and unfortunately they vary in number and sheet names. i'm trying these solutions right now. i hit on using the index yesterday after posting this problem. – Stay-at-home-dad Oct 20 '09 at 16:11
0

Do the sheets you iterate over have a common name format?

Ex)

Sheets(0).name > "Reports"
Sheets(1).name > "Start Here"
Sheets(2).name > "emp.0001"
Sheets(3).name > "emp.0002"
Sheets(4).name > "emp.0003"
Sheets(5).name > "emp.0004"
Sheets(6).name > "End Here"

If so, in your for each loop, just do a Left(ThisWorkSheet.name, 4) = "emp" to verify if it's a sheet you want to reference.

0

In Excel VBA 2013 if you have the worksheets you want to update between tabs "Blankfirst" and "Blanklast" this works.

Use the code below to test it brings back your tab names and then replace your manipulating code in place of MsgBox wks.Name part.

Sub Macro2()

    On Error Resume Next
    GetStartIndex = ThisWorkbook.Worksheets("Blankfirst").Index + 1

    On Error Resume Next
    GetEndIndex = ThisWorkbook.Worksheets("Blanklast").Index - 1

    Dim wks As Worksheet
    Dim i As Integer
    Dim iStart As Integer
    Dim iEnd As Integer

    iStart = GetStartIndex
    iEnd = GetEndIndex


    If iStart > 0 And iEnd > 0 And iEnd > iStart Then
        For i = iStart To iEnd
            Set wks = ThisWorkbook.Worksheets(i)
            MsgBox wks.Name
        Next i
    End If

End Sub
Damian Kozlak
  • 7,065
  • 10
  • 45
  • 51
Samir
  • 1
-1
 Public Sub ITERATE_WORKSHEETS()  
   On Error Resume Next    
   Dim x As Long  
         For x = 0 To 100  
              MsgBox Worksheets(x).Name  
         Next x   
   On Error GoTo 0  
   MsgBox "all done"  
 End Sub  
andrewsi
  • 10,807
  • 132
  • 35
  • 51
Rob
  • 1
  • 1