Select Worksheet using the prefix - excel

I would like to select a worksheet in my activeworkbook and there is only one and it starts with EXP, how do i do that, I am trying something like below.
ActiveWorkbook.Worksheets("EXP*").Select

Loop and find:
Dim sheet As Worksheet
For Each sheet In ActiveWorkbook.Sheets
If (sheet.Name Like "EXP*") Then
sheet.Select
Exit For
End If
Next

Related

Copy image from one worksheet (always named "Template") to worksheet with variable names

I need to copy an image from my invoice template worksheet to another worksheet with variable names. For example, the name of the sheet could be "03-000008" or "04-000005" or any other name. This problem would be easy to solve if the sheets had the same name, but since they are variable, I am struggling. Any help would be much appreciated! Thank you in advance!
Tim suggested that I add the code I am working with (thanks Tim!) Here is the code that almost works, but instead of pasting the image to my new, active invoice sheet, it pastes it right on the template itself.
Sub image()
With ActiveSheet
Set i = Sheets("Template")
Set e = ActiveSheet
i.Shapes.Range(Array("Picture 4")).Select
Selection.Copy
e.Range("b1:b4").Select
ActiveSheet.Paste
End With
End Sub
Try this:
Sub image()
Dim ws As Worksheet
ThisWorkbook.Worksheets("Template").Shapes("Picture 4").Copy
For Each ws In ThisWorkbook.Worksheets
If ws.Name Like "##-######" Then 'check matches pattern [2digits-6digits]
ws.Paste Destination:=ws.Range("B1")
MsgBox "Pasted to " & ws.Name
Exit For 'no need to check further
End If
Next ws
End Sub
If all you need to do is copy the image from Template to the activesheet then:
Sub CopyLogo()
ThisWorkbook.Worksheets("Template").Shapes("Picture 4").Copy
ActiveSheet.Paste Destination:=ActiveSheet.Range("B1")
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

How to declare a worksheet name as wildcard?

I have a worksheet named "Photo Sheet" that i would like to declare in my codes.
Const myWorksheet = "Photo Sheet"
My question, if i have another sheet called "Photo Sheet (2)" is there a way to declare the variable as wildcard that would take any sheet starting with "Photo Sheet*" ?
Not quite clear what you want to do, but you can iterate over the worksheets, using the Like operator to select the ones which have the appropriate name:
Sub test()
Dim ws As Worksheet
For Each ws In Worksheets
If ws.Name Like "Photo Sheet*" Then Debug.Print ws.Name
Next ws
End Sub
This will print the names of all worksheets that begin "Photo Sheet". Of course, rather than printing their names you could e.g. put these worksheets in a collection for further processing.
There isn't if you use an equity operator for testing it, but you can do something similar with Like:
Const SHEET_NAME = "Photo Sheet*"
Sub WhateverYourThingDoes()
Dim ws As Worksheet
For Each ws in Worksheets
If ws.Name Like SHEET_NAME Then
'Your code here.
End If
Next
End Sub
You can't use a wildcard to declare a worksheet directly, so no set shtPhotos = Sheets(Worksheet & "*"). A declaration like that has to be unambiguous or it would potentially return a collection, which can't be assigned to a non-array variable.
So, no wildcards. What you can do is loop through all your worksheets and check whether the sheet's name contains whatever text you're looking for:
Sub FindPhotos()
Const csSheet As String = "Photo Sheet"
Dim shtPhotos As Worksheet
For Each shtPhotos In ActiveWorkbook.Sheets
If InStr(1, shtPhotos.Name, csSheet) <> 0 Then
'do something
End If
Next shtPhotos
End Sub
This is going to look at every worksheet in the active workbook and see if their name contains the text in the constant. This will work fine if you want to perform the same steps with every worksheet that begins "Photo Sheets"; if you only want it to perform those steps with one such sheet, you'd add an Exit For after performing your steps:
For Each shtPhotos In ActiveWorkbook.Sheets
If InStr(1, shtPhotos.Name, csSheet) <> 0 Then
'do something
Exit For
End If
Next shtPhotos
You could also look for a flag on the sheets that are found, so that only sheets that have, say, today's date in a specified cell would be processed:
For Each shtPhotos In ActiveWorkbook.Sheets
If InStr(1, shtPhotos.Name, csSheet) <> 0 AND _
shtphotos.range("A1").value = Date Then
'do something
End If
Next shtPhotos

Finding Part of a Sheet Name

I want to update a worksheet. The name of the worksheet changes with the date.
As an example the worksheet would have been named
"Hello World 6.13" on Monday
"Hello World 6.17" today
How can I looks for the sheet name that starts with "Hello World" and ignores the date code?
They way I would go about this would be to loop through the sheets in the active workbook and make the comparison, and when the correct sheet "Hello World x.xx" is found set it as a reference, and use this reference to run any further code.
Let searchTerm = "Hello World"
For Each ws In ActiveWorkbook.Sheets
If Left(ws.Name, Len(searchTerm)) = searchTerm Then
Set hwSheet = ws
Exit For
End If
Next ws
'do some code eg:
With hwSheet
.Range("A1").Value = "Hi"
End With
So the spreadsheet you want to capture is always the same sheet, in the same workbook? If I've got this right, you can use the codename of the worksheet in the client's workbook, such as Sheet1 instead of the worksheet name.
Dim wb As Workbook, ws as Worksheet
Set wb = Workbooks("Client.xls")
wb.Activate
Set ws = Sheet1
You would have to activate the appropriate workbook before using the sheet codename. To be sure this works, it would be prudent to change the client's sheet codename to something unique (if it isn't already) if that is within your purview.
Posted below is a version of Oliver's code that addresses working with the found sheet inside the loop, rather than the last found match.
A couple of other minor tweaks
The string version of Left$ is quicker than the variant Left
if you set an object in a loop, should set it back to nothing before retesting (which is not evident in the code below as I used the existing ws)
code
Sub Updated()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Sheets
If Left$(ws.Name, 11) = "Hello World" Then
With ws
'do something
End With
End If
Next ws
End Sub
Another option to return all partial sheet matches without a loop is in Adding Sheet Names to Array in Excel VBA
While I liked #Carrosives answer (https://stackoverflow.com/a/37882970/5079799). I decided to functionalize it. In that regard, I didn't want to use LEFT or RIGHT but InSTR.
Here is what I got:
Public Function FindWorksheet(PartOfWSName As String) As Worksheet
For Each ws In ActiveWorkbook.Sheets
If InStr(ws.Name, PartOfWSName) > 0 Then
Debug.Print ws.Name
Set FindWorksheet = ws
Exit For
End If
Next ws
End Function
Sub TestingSpot_Sub()
Dim PartOfWSName As String
PartOfWSName = "Testz"
Dim ws As Worksheet
Set ws = FindWorksheet(PartOfWSName)
ws.Activate
End Sub
This should be enough:
Sub CallTheRealThing()
Call SelectSheets("Sheet")
End Sub
Sub SelectSheets(NameNeededinSheet As String, Optional Looked_Workbook As Workbook)
Dim WorkSheetProject As Worksheet
If Looked_Workbook Is Nothing Then Set Looked_Workbook = ThisWorkbook
For Each WorkSheetProject In Looked_Workbook.Worksheets
If InStr(WorkSheetProject.Name, NameNeededinSheet) Then: WorkSheetProject.Select: Exit Sub
Next WorkSheetProject
End Sub
You may change it to a Function instead of sub to know if it could select the sheet or not

Copy a sheet from one wb to another wb, but copy values?

I have the following code adding sheets from one workbook to another. However, I only want to add the values and not the formulae. How do I achieve this?
Sub publish()
Dim new_wb As Workbook
Dim old_wb As Workbook
Dim i As Long
Dim new_file_path As String
Call refresh_output_sheets
new_file_path = Range("output_path").Value
Set old_wb = ActiveWorkbook
Set new_wb = Workbooks.Add
For Each sh In old_wb.Sheets
If InStr(LCase(sh.CodeName), "output") <> 0 Then
sh.Copy After:=new_wb.Sheets(new_wb.Sheets.Count)
End If
Next sh
Not thoroughly tested but hopefully this will get you close. Replace your copy loop with something like this:
For Each sh In old_wb.Sheets
If InStr(LCase(sh.CodeName), "output") <> 0 Then
sh.Copy
new_wb.Sheets(new_wb.Sheets.Count).PasteSpecial Paste:=xlPasteValues
End If
Next sh
If it's giving you fits, let me know and I'll do some more testing.
Once you have copied a worksheet to the new workbook, activate it and run this:
Sub ClearFormulas()
On Error Resume Next
ActiveSheet.Cells.SpecialCells(xlCellTypeFormulas).ClearContents
End Sub
So basically, remove the formulas after the copy has been made.
Use this:
...
sh.Copy After:=new_wb.Sheets(new_wb.Sheets.Count)
new_wb.Sheets(new_wb.Sheets.Count).Cells.Values=sh.Cells.Values
End If
...
As you know, first statement will copy all data.
Then, new worksheet values are assigned from source, removing all formulas.
I find useful make .Copy before using .Value to copy formats, column widths, ...

Resources