excel vba - iterate through specific sheets in range - excel

I would like to iterate through a list of sheets where the list is determined by a Range.
If I hard-code the list everything is fine.
what I'd like is to refer to a range that contains the sheet names (as it's variable).
Set mySheets = Sheets(Array("sheetOne", "sheetTwo", "sheetThree"))
With ActiveWorkbook
For Each ws In mySheets
'do the stuff here
Next ws
End With
so something like this:
Set mySheets = Sheets(Range("A1:E1"))
Any ideas?

This will work:
Sub MySub()
On Error Resume Next
Set mySheets = Sheets(removeEmpty(rangeToArray(Range("A1:E1"))))
If Err.Number = 9 Then
MsgBox "An error has occurred. Check if all sheet names are correct and retry.", vbCritical
Exit Sub
End If
On Error GoTo 0
With ActiveWorkbook
For Each ws In mySheets
'do the stuff here
Next ws
End With
End Sub
'This will transpose a Range into an Array()
Function rangeToArray(rng As Range) As Variant
rangeToArray = Application.Transpose(Application.Transpose(rng))
End Function
'This will remove empty values and duplicates
Function removeEmpty(arr As Variant) As Variant
Dim result As New Scripting.Dictionary
Dim element As Variant
For Each element In arr
If element <> "" And Not result.Exists(element) Then
result.Add element, Nothing
End If
Next
removeEmpty = result.Keys
End Function
This will load dynamically Sheets contained in your Range.
Edit
Added Function removeEmpty(...) to remove empty values and duplicates.
Note: the Function rangeToArray() is needed to return data in Array() format.
I hope this helps.

I would provide this solution, which does load the sheetnames into an array:
Notice that you have to transpose the Data if the values are ordered horizontal.
Public Sub test()
Dim mySheet As Variant
Dim sheet As Variant
mySheet = Application.Transpose(Tabelle1.Range("A1:E1").Value) 'load your Values into an Array, of course the range can also be dynamic
For Each sheet In mySheet
Debug.Print sheet 'print the sheet names, just for explaining purposes
'it may be necessary to use CStr(sheet) if you want to refer to a sheet like Thisworkbook.Worksheets(CStr(sheet))
'Do something
Next sheet
Erase mySheet 'delete the Array out of memory
End Sub

I demonstrate the code below which does what you want using an animated gif (click for better detail)
Option Explicit
Sub iterateSheets()
Dim sh As Worksheet, shName As String, i As Integer
i = 0
For Each sh In ThisWorkbook.Worksheets
shName = sh.Range("A1").Offset(i, 0)
Worksheets(shName).Range("A1").Offset(i, 0).Font.Color = vbRed
i = i + 1
Next
End Sub

you could do like this:
Sub DoThat()
Dim cell As Range
For Each cell In Range("A1:E1").SpecialCells(xlCellTypeConstants)
If Worksheets(cell.Value2) Is Nothing Then
MsgBox cell.Value2 & " is not a sheet name in " & ActiveWorkbook.Name & " workbook"
Else
With Worksheets(cell.Value2)
'do the stuff here
Debug.Print .Name
End With
End If
Next
End Sub
or the other way around:
Sub DoThatTheOtherWayAround()
Dim sht As Worksheet
For Each sht In Worksheets
If Not IsError(Application.Match(sht.Name, Range("A1:E1"), 0)) Then
'do the stuff here
Debug.Print sht.Name
End If
Next
End Sub
but in this latter case, you wouldn't be advised in case of any A1:E1 value not corresponding to actual sheet name

Related

Having trouble hiding activecell column across tabs using vba

I am trying to hide the activecell column across first 4 tabs. The vba below does not seem to be working. It only hides the activecell in first tab in activesheet. So basically I select highlight first 4 tabs and select cell A1 then use below code:
ActiveCell.EntireColumn.Hidden = True
This only hides column A in first tab, but not tab 2,3,4. Can someone please help get the correct code? Just fyi...it has to be the selected cell and not Range("A1").EntireColumn.Hidden = True, because cell can be any active cell I am trying to hide using an offset function. Any help is appreciated. Thanks.
You could store the location of the active cell, then cycle through each worksheet and use that location to base your column hiding..
Sub tested()
Dim cell_address As String
Dim wsName, ws, c As Range
cell_address = ActiveCell.Address
wsName = Array("Sheet1", "Sheet2", "Sheet3", "Sheet4")
For Each ws In wsName
Sheets(ws).Range(cell_address).EntireColumn.Hidden = True
Next
End Sub
Hide the Same Column in Different Worksheets
There is no way to combine (select) cells from multiple worksheets at the same time so you need to loop through the worksheets and hide each column separately, one after the other.
Usage
Sub HideCellColumnsTEST()
Dim wsIDs(): wsIDs = Array(1, 2, 3, 4)
Dim ws As Worksheet: Set ws = ActiveSheet
Dim cell As Range: Set cell = ws.Range("A1")
'or:
'Set cell = ActiveCell
'Set cell = ActiveCell.Offset(, 3) '...etc.
HideCellColumns cell, wsIDs
End Sub
The Method
Sub HideCellColumns(ByVal cell As Range, ByVal wsIDs As Variant)
Dim CellAddress As String: CellAddress = cell.Address
Dim wb As Workbook: Set wb = cell.Worksheet.Parent
Dim ws As Worksheet, wsID
For Each wsID In wsIDs
On Error Resume Next
Set ws = wb.Worksheets(wsID)
On Error GoTo 0
If Not ws Is Nothing Then ' worksheet exists
ws.Range(CellAddress).EntireColumn.Hidden = True
Set ws = Nothing ' reset for the next iteration
'Else ' worksheet doesn't exist; do nothing!?
End If
Next wsID
End Sub

Why using .Copy After:= a sheet containing a chart causes its data series to change in the resulting sheet's chart?

I'm using the code below to duplicate a template sheet and give it a couple of characteristics according to the selected cell's content. It works fine up to a point, but since it contains a chart, the resulting sheet's chart is grabbing data from different ranges, than the ones set in the template sheet:
Sub AddSheets()
Dim cell As Excel.Range
Dim allShares As Excel.Worksheet
Dim wbToAddSheetsTo As Excel.Workbook
Dim destTicker As Range
Dim startDate As Range
Dim endDate As Range
Dim sheetName As String
Dim sh 'As Sheets
Set allShares = ActiveWorkbook.Worksheets("all shares")
Set wbToAddSheetsTo = ActiveWorkbook
Application.ScreenUpdating = False
If Selection.Column > 1 Then
MsgBox "Please make sure you Select at least a ticker in column A"
Exit Sub
Else
For Each cell In Selection
With wbToAddSheetsTo
For i = 1 To ActiveWorkbook.Worksheets.Count
If Worksheets(i).Name = cell.Value Then
MsgBox "This name Is already in use!"
Worksheets(cell.Value).Activate
Exit Sub
End If
Next
allShares.Copy After:=.Sheets(.Sheets.Count)
ActiveSheet.Name = cell.Value
ActiveSheet.Range("G4").Value = cell.Value
ActiveSheet.Range("J4").Formula = "='all shares'!$J$4"
ActiveSheet.Range("J5").Formula = "='all shares'!$J$5"
ExtractData
On Error GoTo 0
End With
Next cell
wbToAddSheetsTo.Worksheets("List of Stocks").Activate
End If
Application.ScreenUpdating = True
End Sub
I'm not sure I'm missing something here.
Thanks.

EXCEL VBA: Looking for code to rename a specified sheet with specified name, both based on cell values

So, say for instance I have 2 sheets in my workbook... Page1 and OldName.
On sheet Page1 in cell A1 there is the value OldName (where "OldName" happens to be sheet name of the sheet I would like to rename).
Also on Page1 in cell A2, there is the value NewName (where "NewName" is the name I would like to change the sheet specified in cell A1 to).
I am Trying to come up with code that uses the the cell A1 to identify which sheet I would like to rename and then use the cell A2 as the source for the rename value.
Any suggestions?
You may try something along these lines:
Sub Test()
Dim sht As Worksheet
With ThisWorkbook
For Each sht In .Worksheets
If sht.Name = .Worksheets("Page1").Cells(1, 1).Value Then
sht.Name = .Worksheets("Page1").Cells(2, 1).Value
Exit For
End If
Next
End With
End Sub
try this simple loop
Sub ChangeNameLoop()
Dim wb As Workbook
Dim ws As Worksheet
Dim OldName As String, NewName As string
Set wb = ThisWorkbook
OldName = ActiveSheet.Range("A1") ' location of names
NewName = ActiveSheet.Range("A2")
For Each ws In wb.Worksheets
If ws.Name = OldName Then
ws.Name = NewName
End If
Next ws
End Sub
No need to loop. This will do what you want. This code will replace the sheet name if found else will do nothing.
Option Explicit
Sub Sample()
On Error Resume Next
With ThisWorkbook
.Sheets(.Sheets("Page1").Cells(1, 1).Value2).Name = _
.Sheets("Page1").Cells(2, 1).Value2
End With
On Error GoTo 0
End Sub
Or something like this
Option Explicit
Sub Sample()
Dim ws As Worksheet
With ThisWorkbook
On Error Resume Next
Set ws = .Sheets(.Sheets("Page1").Cells(1, 1).Value2)
On Error GoTo 0
If Not ws Is Nothing Then ws.Name = _
.Sheets("Page1").Cells(2, 1).Value2
End With
End Sub

(VBA) apply to all, except one specific

Hi everyone i made a button on excel using VBA modules,The code works on the active sheet but what im looking for is to be applied to more sheets, not just the active sheet where the button is placed.
Sub Botón1_Haga_clic_en()
Call Worksheet_Calculate
End Sub
'apply cells colors from single-cell formula dependencies/links
Private Sub Worksheet_Calculate()
Dim Cel As Range
Dim RefCel As Range
On Error Resume Next
For Each Cel In ActiveSheet.UsedRange
If Cel.HasFormula Then
Set RefCel = Evaluate(Mid(Cel.Formula, 2))
Cel.Interior.Color = RefCel.Interior.Color
End If
Next Cel
End Sub
Try the code below :
Option Explicit
Sub Botón1_Haga_clic_en()
Dim wsName As String
Dim ws As Worksheet
wsName = ActiveSheet.Name
For Each ws In ThisWorkbook.Worksheets
If Not ws.Name Like wsName Then '<-- is worksheet's name doesn't equal the ActiveSheet's
ApplyCellColors ws ' <-- call you Sub, with the worksheet object
End If
Next ws
End Sub
'=======================================================================
'apply cells colors from single-cell formula dependencies/links
Private Sub ApplyCellColors(ws As Worksheet)
Dim Cel As Range
Dim RefCel As Range
On Error Resume Next
For Each Cel In ws.UsedRange
If Cel.HasFormula Then
Set RefCel = Evaluate(Mid(Cel.Formula, 2))
Cel.Interior.Color = RefCel.Interior.Color
End If
Next Cel
End Sub
Your problem can be translated to something like How to loop over all sheets and ignore one of them?
This is a good way to do it:
Option Explicit
Option Private Module
Public Sub TestMe()
Dim wks As Worksheet
For Each wks In ThisWorkbook.Worksheets
If wks.name = "main" Then
Debug.Print "Do nothing here, this is the active sheet's name"
Else
Debug.Print wks.name
End If
Next wks
End Sub
Pretty sure, that you should be able to fit it in your code.

Rename Worksheet with Dropdown list

I am using the below code to rename worksheet.
Option Explicit
Sub RenWSs()
Dim ws As Worksheet
Dim shtName
Dim newName As String
Dim i As Integer
Dim RngStr As String
RngStr = Application.InputBox(prompt:="Select the Range for the new Sheet's name", Type:=2)
For Each ws In Worksheets
With ws
If Trim(.Range(RngStr)) <> "" Then
shtName = Split(Trim(.Range(RngStr)), " ")
newName = shtName(0)
On Error GoTo ws_name_error
.Name = .Range(RngStr)
GoTo done
repeat:
.Name = newName & i
GoTo done
ws_name_error:
i = i + 1
Resume repeat
End If
End With
On Error GoTo 0
done:
Next
End Sub
In this i am selecting the new name through Input Box and its working fine. Now what i want is, before calling the input box, the below process has to be done.
I have names in drop down list, each names in drop down list to be updated one by one in all worksheets like J16 is the cell.
Please help me
The code below will lopp through all ws sheets, and modifies the value of cell in "J16" to "Test 1" (just for testing purposes).
Option Explicit
Sub ModifyDropDownValue()
Dim ws As Worksheet
For Each ws In Worksheets
With ws
' modify the value in cell J16
.Range("J16").Value = "Test 1"
End With
Next ws
End Sub

Resources