Looping through different sheets - vba

I would appreciate your help with the macro I am trying to create.
I have an xls file with a bunch of worksheets, some of which named "1", "2", "3", and so forth. I would like to create a macro that loops only through those 'number-named' worksheets, hence NOT according to the index as in the code below. (Sheet "1" is not the first sheet in the workbook). Before the loop I need to define both the cell range and sheets.
Below is my (wrong) attempt.
Sub Refresh ()
Dim i As Integer
Dim rng As Range
Set rng = Range("A10:TZ180")
For i = 1 To 30
Sheets(i).Activate
rng.Select
rng.ClearContents
Application.Run macro:="xxx"
Next i
End Sub

dim w as worksheet
for each w in activeworkbook.worksheets
if isnumeric(w.name) then
w.range("A10:TZ180").clearcontents
xxx()
end if
next

If the macro "xxx()" requires a selected range you just need to add a select statement. (Borrowing from GSerg)
Dim w As Worksheet
For Each w In ActiveWorkbook.Worksheets
If IsNumeric(w.Name) Then
w.Range("A10:TZ180").ClearContents
w.Range("A10:TZ180").Select
Application.Run macro:="xxx"
End If
Next
To clear up your misunderstanding about assigning a range see the following:
Sub Refresh()
Dim ws As Worksheet
Dim rng As Range
Dim i As Integer
For Each ws In ActiveWorkbook.Worksheets
If IsNumeric(ws.Name) Then
'you must activate the worksheet before selecting a range on it
ws.Activate
'note the qualifier: ws.range()
Set rng = ws.Range("A10:TZ180")
'since the range is on the active sheet, we can select it
rng.Select
rng.ClearContents
Application.Run macro:="xxx"
End If
Next
End Sub
Sub test2()
Dim ws As Worksheet
Dim rg As Range
Dim arrSheets As Variant
arrSheets = Array("Sheet1", "Sheet2", "Sheet3")
Dim x As Long
For x = LBound(arrSheets) To UBound(arrSheets)
Set ws = Worksheets(arrSheets(x))
ws.Activate
'...
Next
End Sub
Sub test3()
Dim ws As Worksheet
Dim x As Long
For x = 1 To 20
Set ws = Worksheets(CStr(x))
ws.Activate
'...
Next
End Sub

try this
Sub main()
Dim shtNames As Variant, shtName As Variant
shtNames = Array(1, 2, 3, 4) '<== put your actual sheets "number name"
For Each shtName In shtNames
With Worksheets(CStr(shtName))
.Range("A10:TZ180").ClearContents
.Range("A10:TZ180").Select
Application.Run macro:="MacroToRun"
End With
Next shtName
End Sub
Sub MacroToRun()
MsgBox "hello from cells '" & Selection.Address & "' in sheet '" & ActiveCell.Parent.Name & "'"
End Sub

Related

Counting cells of worksheets within another workbook

I have one xlsm file with a single button in it which, when clicked, is supposed to open a separate workbook and search through all contained worksheets for cells of a specific colour.
The problem is, instead of searching the other workbook's worksheets, it just searches itself. I'm new to VBA, and feel like i've been round the internet 6 times trying to solve this. What am I doing wrong here?
Private Sub CommandButton1_Click()
Dim wb As Workbook
Dim ws As Worksheet
Dim holdCount As Integer
Dim cellColour As Long
Dim cell As Range, rng As Range
Set wb = Workbooks.Open("blahblahblah.xls")
Set rng = Range("A1:A20")
holdCount = 0
cellColour = RGB(255, 153, 0)
For Each ws In wb.Worksheets
For Each cell In rng
If cell.Interior.Color = cellColour Then
holdCount = holdCount + 1
End If
Next cell
Next ws
MsgBox "found " & holdCount
End Sub
It looks to me like you aren't fully qualifying your Range
Move this inside of your ws loop instead of where it is now.
Set rng = ws.Range("A1:A20")
BraX pointed out that I needed to qualify the Range WITHIN the For Each ws loop, so here is the fixed and working code. Again, all credit to Brax.
Private Sub CommandButton1_Click()
Dim wb As Workbook
Dim ws As Worksheet
Dim holdCount As Integer
Dim cellColour As Long
Dim cell As Range, rng As Range
Set wb = Workbooks.Open("blahblahblah.xls")
holdCount = 0
cellColour = RGB(255, 153, 0)
For Each ws In wb.Worksheets
With ws
Set rng = ws.Range("A1:A20")
For Each cell In rng
If cell.Interior.Color = cellColour Then
holdCount = holdCount + 1
End If
Next cell
End With
Next ws
MsgBox "found " & holdCount
End Sub

Subscript out of range - runtime error 9

can you please advise why the below code does not select the visible sheets, but ends in a runtime error. This is driving me crazy. Thanks for any help.
Sub SelectSheets1()
Dim mySheet As Object
Dim mysheetarray As String
For Each mySheet In Sheets
With mySheet
If .Visible = True And mysheetarray = "" Then
mysheetarray = "Array(""" & mySheet.Name
ElseIf .Visible = True Then
mysheetarray = mysheetarray & """, """ & mySheet.Name
Else
End If
End With
Next mySheet
mysheetarray = mysheetarray & """)"
Sheets(mysheetarray).Select
End Sub
Long story short - you are giving a string (mysheetarray) when it is expecting array. VBA likes to get what it expects.
Long story long - this is the way to select all visible sheets:
Option Explicit
Sub SelectAllVisibleSheets()
Dim varArray() As Variant
Dim lngCounter As Long
For lngCounter = 1 To Sheets.Count
If Sheets(lngCounter).Visible Then
ReDim Preserve varArray(lngCounter - 1)
varArray(lngCounter - 1) = lngCounter
End If
Next lngCounter
Sheets(varArray).Select
End Sub
You should define Dim mySheet As Object as Worksheet.
Also, you can use an array of Sheet.Names that are visible.
Code
Sub SelectSheets1()
Dim mySheet As Worksheet
Dim mysheetarray() As String
Dim i As Long
ReDim mysheetarray(Sheets.Count) '< init array to all existing worksheets, will optimize later
i = 0
For Each mySheet In Sheets
If mySheet.Visible = xlSheetVisible Then
mysheetarray(i) = mySheet.Name
i = i + 1
End If
Next mySheet
ReDim Preserve mysheetarray(0 To i - 1) '<-- optimize array size
Sheets(mysheetarray).Select
End Sub
I have tried to explain the Sheets a little, HTH.
Note: Sheets property is defined on Workbook and on Application objects, both works and returns the Sheets-Collection.
Option Explicit
Sub SheetsDemo()
' All sheets
Dim allSheets As Sheets
Set allSheets = ActiveWorkbook.Sheets
' Filtered sheets by sheet name
Dim firstTwoSheets As Sheets
Set firstTwoSheets = allSheets.Item(Array("Sheet1", "Sheet2"))
' or simply: allSheets(Array("Sheet1", "Sheet2"))
' Array("Sheet1", "Sheet2") is function which returns Variant with strings
' So you simply need an array of sheet names which are visible
Dim visibleSheetNames As String
Dim sh As Variant ' Sheet class doesn't exist so we can use Object or Variant
For Each sh In allSheets
If sh.Visible Then _
visibleSheetNames = visibleSheetNames & sh.Name & ","
Next sh
If Strings.Len(visibleSheetNames) > 0 Then
' We have some visible sheets so filter them out
visibleSheetNames = Strings.Left(visibleSheetNames, Strings.Len(visibleSheetNames) - 1)
Dim visibleSheets As Sheets
Set visibleSheets = allSheets.Item(Strings.Split(visibleSheetNames, ","))
visibleSheets.Select
End If
End Sub

Type mismatch error VBA loop through worksheets

I keep getting a type mismatch error and have tried changing the type a few times. I'm just trying to loop through each worksheet and a specified range to see if that word exists in every cell of that range.
Sub CheckWord()
Dim arrVar As Variant
Dim ws As Worksheet
Dim strCheck As Range
Set arrVar = ActiveWorkbook.Worksheets
'MsgBox (arrVar)
For Each ws In arrVar
If ws.Range("C9:G20").Value = "Word" Then
MsgBox (True)
End If
Next ws
End Sub
When you have a range with many columns, it creates an array.
Taking the array into consideration like so:
Sub CheckWord()
Dim arrVar As Variant
Dim ws As Worksheet
Dim strCheck As Range
Set arrVar = ActiveWorkbook.Worksheets
'MsgBox (arrVar)
For Each ws In arrVar
For each col in ws.Range("C9:G20").Cells
if col.Value = "Word" Then
MsgBox (True)
end if
End If
Next ws
End Sub
You can't get the value of ws.Range("C9:G20") and compare it to one string. You've selected multiple cells. If you want to return True when nay one of these cells contains "Word" or when all of them contain "Word" you'll need to iterate over them.
This is an example of how to return whether or not your range contains "Word" anywhere at least once
Function CheckWord()
Dim arrVar As Variant
Dim ws As Worksheet
Set arrVar = ActiveWorkbook.Worksheets
For Each ws In arrVar
Dim c
For Each c In ws.Range("C9:G20").Cells
If c = "Word" Then
CheckWord = True
Exit Function
End If
Next c
Next ws
End Function
Sub CheckWord()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
If Not ws.Range("C9:G20").Find(What:="Word", LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False) Is Nothing Then MsgBox "Found in " & ws.Name
Next ws
End Sub

Sorting Macro not functioning properly

I've written a macro to cut and paste rows from one sheet ("New Providers - FPPE") into multiple sheets based on a column (H). When I first used it, it was working well, but when I have added additional data to the sorting sheet ("New Providers - FPPE") it is not fully functioning. The macro continues to cut the rows from "New Providers - FPPE" but the rows fail to populate onto the sheets. I have no idea where the rows are going. Does anyone have any insight as to what could be happening? I'm very new to writing macros so any help is appreciated!
Option Explicit
Sub Fr33M4cro()
Dim sh33tName As String
Dim custNameColumn As String
Dim i As Long
Dim stRow As Long
Dim customer As String
Dim ws As Worksheet
Dim sheetExist As Boolean
Dim sh As Worksheet
sh33tName = "New Providers - FPPE"
custNameColumn = "H"
stRow = 7
Set sh = Sheets(sh33tName)
For i = sh.Range(custNameColumn & sh.Rows.Count).End(xlUp).Row To stRow Step -1
customer = sh.Range(custNameColumn & i).Value
For Each ws In ThisWorkbook.Sheets
If StrComp(ws.Name, customer, vbTextCompare) = 0 Then
sheetExist = True
Exit For
End If
Next
If sheetExist Then
CopyRow i, sh, ws, custNameColumn
Else
InsertSheet customer
Set ws = Sheets(Worksheets.Count)
CopyRow i, sh, ws, custNameColumn
End If
Reset sheetExist
Next i
End Sub
Private Sub CopyRow(i As Long, ByRef sh As Worksheet, ByRef ws As Worksheet, custNameColumn As String)
Dim wsRow As Long
wsRow = ws.Range(custNameColumn & ws.Rows.Count).End(xlUp).Row + 1
ws.Rows(wsRow).EntireRow.Value = sh.Rows(i).EntireRow.Value
sh.Rows(i).EntireRow.Delete
End Sub
Private Sub Reset(ByRef x As Boolean)
x = False
End Sub
Private Sub InsertSheet(shName As String)
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = shName
End Sub
I suggest you change your InsertSheet sub to a function that returns a reference to the inserted worksheet:
Function InsertSheet(shName As String) As Worksheet
Set InsertSheet = Worksheets.Add(After:=Worksheets(Worksheets.Count))
InsertSheet.Name = shName
End Function
then change this part of the code:
InsertSheet customer
Set ws = Sheets(Worksheets.Count)
CopyRow i, sh, ws, custNameColumn
to this:
Set ws = InsertSheet(customer)
CopyRow i, sh, ws, custNameColumn

Code to be run on multiple specific sheets

I want to run a code on multiple sheets. The sheet names are: Sheet1, Sheet2, 1, 2 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 and Summary. I define my sheets of interest= (1, 2, 3, 4 and Summary). The code should run only on these sheets. If any sheet in sheets of interest is not present, it should run for all other sheet of interest, i.e. if 1,2 are not present it should run for 3,4 and Summary.
you can loop each sheets into your workbook
Option Explicit
Dim ws As Worksheet, a As Range
Sub forEachWs()
For Each ws In ActiveWorkbook.Worksheets
Call yourcode
Next
End Sub
For Each sht In ThisWorkbook.Sheets
If sht.Name <= 12 Then
'
'
'MsgBox sht.Name
End If
Next
As an alternative to For...Next Loop this will work on all worksheets that are numbered:
Sub AllSheets()
Dim wrkSht As Worksheet
For Each wrkSht In ThisWorkbook.Worksheets
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Or any workbook.worksheets reference: '
'For Each wrkSht In ActiveWorkbook.Worksheets '
'For Each wrkSht In Workbooks("Book2.xlsx").Worksheets '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If IsNumeric(wrkSht.Name) Then
'Your code here.
End If
Next wrkSht
End Sub
As a complete alternative you could put the required sheet names in a range in the workbook, give the range a defined name and use this:
Sub All()
Dim rCell As Range
Dim wrkSht As Worksheet
For Each rCell In Range("MyDefinedSheetNameRange")
If WorkSheetExists(rCell.Value) Then
Set wrkSht = ThisWorkbook.Worksheets(rCell.Value)
'Do stuff with wrksht
End If
Next rCell
End Sub
Public Function WorkSheetExists(SheetName As String) As Boolean
Dim wrkSht As Worksheet
On Error Resume Next
Set wrkSht = ThisWorkbook.Worksheets(SheetName)
WorkSheetExists = (Err.Number = 0)
Set wrkSht = Nothing
On Error GoTo 0
End Function
This is a very basic question and you should find the answer by simply Googling it. Though here combined with this is the answer for you.
Sub WorksheetLoop()
Dim WS_Count As Integer
Dim I As Integer
Dim found As Integer
Dim index As Integer
Dim sheetnames {"1", "2", "Summary"}
' Set WS_Count equal to the number of worksheets in the active
' workbook.
WS_Count = ActiveWorkbook.Worksheets.Count
' Begin the loop.
For I = 1 To WS_Count
found = 0;
For index = 0 To numbers.GetUpperBound(0)
If sheetnames(index) = ActiveWorkbook.Worksheets(I).Name Then
found = 1
EndIf
Next
If found = 1 Then
' Insert your code here.
' The following line shows how to reference a sheet within
' the loop by displaying the worksheet name in a dialog box.
MsgBox ActiveWorkbook.Worksheets(I).Name
EndIf
Next I
End Sub