Sub-group worksheets / list objects - excel

Is there a way to make groups of worksheets or list objects that can then be called when doing looping functions? So for example I have some lines of code that I want to run on a handful of tables that exist on a few worksheets in a much larger excel file. Currently I use code such as the following:
Dim sht As Worksheet
Dim lstobj As ListObject
For Each sht In ThisWorkbook.Worksheets
For Each lstobj In sht.ListObjects
Blah blah blah
Next lstobj
Next sht
However I only really need the code to loop through 5 or 6 tables that exist on 3 worksheets so looping through every single sheet and list object is a waste of time and ultimately will cause me problems when I don't want to run code on some objects. Can I make a sub-group of worksheets and a sub-group of tables that I can run the code on or will I have to call each one individually?

If you have specified/named objects, you can assign them in an array and loop through them.
Here's an example of doing so with an Excel spreadsheet with 4 sheets, but the loop only goes through 3 of them (1, 2 and 4).
Dim worksheets(2) As Excel.Worksheet
Set worksheets(0) = ThisWorkbook.Sheets(1)
Set worksheets(1) = ThisWorkbook.Sheets(2)
Set worksheets(2) = ThisWorkbook.Sheets(4)
Dim worksheetVar As Variant ' Excel.Worksheet
For Each worksheetVar In worksheets
MsgBox worksheetVar.Name
If worksheetVar.ListObjects.Count > 0 Then
MsgBox "Has List Objects"
End If
Next

Related

Making sheet name the same as cell value

I am currently working on macro in a workbook with multiple worksheets, that aims to show and hide certain worksheets based on the values in a master worksheet. The worksheet names are also contained in the master worksheet and the main procedure looks at these values when referencing to a worksheet it needs to show or hide. The problem with this method is that, the macro will produce errors if the user changes the worksheet tab names. I was hoping to insert an additional procedure that makes the tab names of each worksheet equal to the values in the respective cell of the master worksheet. I came up with the following:
Sub SheetName()
If Not ActiveWorkbook Is ThisWorkbook Then Exit Sub
Dim DataImport As Worksheet
Set DataImport = ThisWorkbook.Worksheets("Data Import")
DataImport.Range("A13").Value = Sheet1.Name
End Sub
This code works fine but there are about 100+ worksheets in this workbook. I was wondering if there is a more efficient way to do this, as opposed to typing the same procedure 100 times. I've tried storing the worksheet code names in an array and looping the same procedure through the array, for example:
Sub test()
Dim DataImport As Worksheet
Set DataImport = ThisWorkbook.Worksheets("Data Import")
Dim index As Long
Dim ws(0 To 2) As Worksheet
Set ws = Array(Sheet1, Sheet2, Sheet3)
For i = 13 To 14
index = i - 13
DataImport.Cells(i, "A").Value = ws(index).Name
Next i
End Sub
but the error message "Can't Assign to Array" shows up. Sorry in advance if my code looks garbage, I am still new to VBA and I still have quite a lot to learn.
If you list the sheet codenames in ColA of your master sheet, then this code will update columns B and C with the current sheet tab names and indexes respectively:
Sub UpdateIndex()
Dim ws As Worksheet, cn As String, m
For Each ws In ThisWorkbook.Worksheets
cn = ws.CodeName
If cn <> DataImport.CodeName Then
'look for the codename in the Import sheet
m = Application.Match(cn, DataImport.Columns(1), 0)
If Not IsError(m) Then
'got a match - update this row
DataImport.Cells(m, "B").Value = ws.Name 'tab name
DataImport.Cells(m, "C").Value = ws.Index 'sheet index
End If
End If
Next ws
End Sub
Assumes you set the code name for your "Data Import" worksheet to DataImport.
If your code is driven by the sheet codename, it doesn't matter whether the user renames the tabs or changes the sheet order.
For your second attempt, you can use Excel built-in Sheets object and Workbook.Sheets collection:
Sub test()
Dim DataImport As Worksheet
Set DataImport = ThisWorkbook.Worksheets("Data Import")
Dim index As Long
Dim ws As Excel.Sheets
Set ws = ThisWorkbook.Sheets
For i = 13 To 14
index = i - 13
DataImport.Cells(i, "A").Value = ws(index).Name
Next i
End Sub

In XL using VBA, is there a simple way to step through every table in a workbook and set every cell value to 0?

I'm working on an XL workbook that has multiple tables on multiple sheets. As I go along, I've been adding to and modifying a subroutine that can zeroise the tables. This is time consuming (and error-prone), especially as I keep having to modify my tables at the whim of my beloved users. Can anyone come up with a routine that will just find each table and zeroise it?
Many thanks.
This will loop through each table in your workbook and set all values to 0
Public Sub PopulateTables()
Dim ws As Worksheet
Dim tbl As ListObject
For Each ws In ThisWorkbook.Sheets
For Each tbl In ws.ListObjects
tbl.DataBodyRange.Value2 = 0
Next tbl
Next ws
End Sub

VBA code to call different macro depending on part of Worksheet name

I am working on a macro that will cycle through all of the sheets in the active workbook and will then clear a certain part of a particular worksheet, based on whether one of the relevant keywords is contained in the worksheet name. In each case the worksheet name will be different, but any I want to clear will contain one of the key words below.
I have set up a separate macro to clear the range of cells in each case. If the Worksheet name does not contain any of the keywords, I want the macro to move onto the next worksheet.
My ultimate aim is to be able to apply this to numerous different workbooks, as the project I am working on is split by region, with a separate Excel file per region.
The code I have been trying is below. There are no errors appearing when I run the code, the code does not seem to run either, in fact nothing at all happens!
Any guidance or advice would be greatly appreciated.
Sub Loop_Customer_Sheets()
Dim ws As Integer
Dim i As Integer
ws = ActiveWorkbook.Worksheets.Count
For i = 1 To ws
If ActiveSheet.Name Like "*ABC*" Then
Call ABCInfoClear
ElseIf ActiveSheet.Name Like "*DEF*" Then
Call DEFInfoClear
ElseIf ActiveSheet.Name Like "*GHI*" Then
Call GHIInfoClear
Else:
End If
Next i
End Sub
"Nothing at all happens" - fixing the issue with your code:
Your issue is that you are looping through the number of sheets, but you are only checking the ActiveSheet, which never changes! Replace your code with
ws = ActiveWorkbook.Worksheets.Count
For i = 1 To ws
With ActiveWorkbook.WorkSheets(i)
If .Name Like "*ABC*" Then
ABCInfoClear
ElseIf .Name Like "*DEF*" Then
DEFInfoClear
ElseIf ActiveSheet.Name Like "*GHI*" Then
GHIInfoClear
End If
End With
Next i
Note: you don't need the Call keyword, you can just call subs as presented above.
Alternative solutions
A better option than having numerous macros might be to create a generic sub like
Sub ClearRangeInSheet(rangeAddress As String, sh As WorkSheet)
Dim myRange As Range
Set myRange = sh.Range(rangeAddress)
myRange.ClearContents
' Any other cell clearing code e.g. for formatting here
End Sub
Then call in the loop
Dim wsCount as Long
wsCount = ActiveWorkbook.WorkSheets.Count
For i = 1 to wsCount
With ActiveWorkbook
If .WorkSheets(i).Name Like "*ABC*" Then
' Always pass ".WorkSheets(i)", but change the range address as needed
ClearRangeInSheet("A1:A20", .WorkSheets(i))
ElseIf ' Other worksheet name conditions ...
End If
End With
Next I
As suggested in the comments, you could ditch indexing the sheets, and just loop through the sheet objects themselves:
Dim wksht as WorkSheet
For Each wksht In ActiveWorkbook.WorkSheets
If wksht.Name Like "*ABC*" Then
' Always pass wksht but change the range address as needed
ClearRangeInSheet("A1:A20", wksht)
ElseIf ' Other worksheet name conditions ...
End If
Next wksht

With statement for multiple worksheets?

I am repeating a set of actions for certain sheets in a workbook currently by
For Each ws In Worksheets
Select Case ws.Name
Case "2015", "2016", "Rate", "Month"
'code here
End Select
Next ws
which seems awfully inefficient XD
Is it possible to do something like
With ws1, ws2, ws3
'code here
end with
I don't have that many sheets so the loop only takes ~2 seconds but there must be a quicker/elegant way?
Worksheets is a collection that contains all sheets in the current workbook.
To simplify you code you could create your own collection with just the sheets to be processed and use this instead. Then you wouldn't need the select case statement to limit which sheets are processed by the loop.
However, seeing up a collection is probably more work than doing it the way you have done. Although it is the OO way of don't it.
So in a module you might do something like this:
Sub aa()
Dim colSheets As Collection
Set colSheets = New Collection
colSheets.Add Sheet1 ' here I use the object name from the VBA "(Name)" property
colSheets.Add Worksheets("MyWorksheetName")
colSheets.Add Worksheets("SummarySheet")
Dim sht As Worksheet
For Each sht In colSheets
Debug.Print sht.Name
Next sht
Set colSheets = Nothing
End Sub

Updating multiple Excel Sheets

I am creating an excel workbook with multiple different sheets. I want to be able to add a row to any sheet and have it reflected on the first sheet. I am having trouble with this since I want to add them to different sheets based on a condition. Is there any easy way to do this.
Here is a template for having multiple worksheets in VBA and setting values b/w them
Sub test ()
Dim ws as worksheet
Dim ws2 as worksheet
Set ws = Worksheets(1)
Set ws2 = Worksheets(2)
ws2.Range("A") = ws.Range("A")
End Sub

Resources