Selecting a worksheet based on a cell value in Excel VBA - excel

I am trying to select a particular page based on cell value U2. I am using the backend Excel names not the display names for the sheets. "Sheet11" is the sheet I am currently trying to connect to. I have tried the following codes, but getting run-time error 9, out of range.
What could I try next?
Thanks
'#1
Dim ws As Worksheet
ws = Range("U2")
Set ws = ActiveSheet
'#2
(Range("U2").Activate
'#3
Sheet11.Activate
Works but no variable
'#4
Sheets(Range("U2").Text).Activate
'#5
Sheets(Range("U2").Value).Activate
'#6
Dim GetString As String
GetString = Range("U2")
GetString.Activate

Is this what you are looking for?
Sheets(ActiveSheet.Range("U2").Value).Select

Reference a Worksheet By Its Code Name
Option Explicit
Sub RefByCodeName()
' Write the code name to a string variable ('wscName').
' Adjust the worksheet!
Dim wscName As String: wscName = CStr(Sheet1.Range("U2").Value)
' Using the 'RefWorksheetByCodeName' function, attempt to reference
' the worksheet ('ws') by its code name.
Dim ws As Worksheet: Set ws = RefWorksheetByCodeName(wscName, ThisWorkbook)
' Validate the worksheet.
If ws Is Nothing Then
MsgBox "No worksheet with the code name '" & wscName & "' found.", _
vbCritical
Exit Sub
End If
' Continue, e.g.:
'MsgBox "Name: " & ws.Name & vbLf & "Code Name: " & ws.CodeName, _
vbInformation
' Make sure the workbook is active.
If Not ThisWorkbook Is ActiveWorkbook Then ThisWorkbook.Activate
' Select the worksheet.
ws.Select
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: In a workbook ('wb'), references a worksheet
' by its code name ('WorksheetCodeName').
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function RefWorksheetByCodeName( _
ByVal WorksheetCodeName As String, _
ByVal wb As Workbook) _
As Worksheet
Dim ws As Worksheet
For Each ws In wb.Worksheets
If StrComp(ws.CodeName, WorksheetCodeName, vbTextCompare) = 0 Then
Set RefWorksheetByCodeName = ws
Exit Function
End If
Next ws
End Function

Sheets have 3 ways of referring to them:
Name (What you see on the tab at the bottom)
Index (A number representing the sheet's position in the workbook, i.e. this will change if you change the position of a sheet)
CodeName (This is what you refer to as the back end excel name)
You can select a sheet using any of these. If I had a workbook with tabs named after months in Jan to Dec order and I haven't changed the code names the code to select November using each would be as follows:
1.Name Worksheets("November").Select
2.Index Worksheets(11).Select
3.CodeName Sheet11.Select
Unlike name and index you can refer to the codename directly as it is an object.
the following code uses the index to loop through the sheet codenames comparing them to the value in U2 when it is the same as U2 it will select the sheet.
Dim lCodeName As String
Dim lWSCount, lCount As Integer
lCodeName = ActiveSheet.Range("U2").Value
lWSCount = ActiveWorkbook.Worksheets.Count
For lCount = 1 To lWSCount
If Worksheets(lCount).CodeName = lCodeName Then
Worksheets(lCount).Select
Else
End If
Next

Related

excel vba code error(subscript out of range)

Hi all I had a code in excel vba that makes me able to change sheet name according to cell value i right click on sheet name then select (view code ) then paste the code it worked well with the sheet i did a simple macro that copy the sheet content into another new sheet then paste the code that changes the sheet name with the cell value but i got an error i just need a macro that add new sheet and copy the current sheet content into the new and make the sheet name dependent on cell value (b3)
i have 0 experience in visual basic
here is some screenshots
thanks for helping me
this the sheet name code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("B3")) Is Nothing Then
ActiveSheet.Name = ActiveSheet.Range("B3")
End If
End Sub
i have already explained that THAT
Create a Copy of the Active Sheet
Copy this code into a standard module, e.g. Module1.
Option Explicit
Sub CopyActiveSheet()
' In the worst case scenario, you'll end up with an additional worksheet
' that could not be renamed. If you want to keep this worksheet,
' set DeleteIfCannotRename to False.
Const DeleteIfCannotRename As Boolean = True
' Invalidate the active sheet.
Dim sh As Object: Set sh = ActiveSheet
If sh Is Nothing Then Exit Sub ' no visible workbooks open
If Not TypeOf sh Is Worksheet Then Exit Sub ' not a worksheet
' Reference the source worksheet.
Dim sws As Worksheet: Set sws = ActiveSheet
' Create a copy.
sws.Copy After:=sws
' Reference the copy.
Dim dws As Worksheet: Set dws = ActiveSheet
' Write the value form 'B3' to a variable.
Dim dName As String: dName = CStr(dws.Range("B3").Value)
Dim ErrNumber As Long
' Prevent error if a sheet with the same name already exists
' or the value in 'B3' doesn't contain a valid worksheet name.
On Error Resume Next ' turn on error-trapping
' Attempt to rename.
dws.Name = dName
ErrNumber = Err.Number ' store the error number in a variable
On Error GoTo 0 ' turn off error trapping
' Delete and inform. Out-comment or delete the 'MsgBox' line(s)
' if the message box is too annoying.
If DeleteIfCannotRename Then ' will delete
If ErrNumber <> 0 Then
Application.DisplayAlerts = False
dws.Delete
Application.DisplayAlerts = True
MsgBox "Could not rename to '" & dName & "' so it got deleted.", _
vbCritical, "CopyActivesheet"
End If
Else ' will not delete
MsgBox "Could not rename to '" & dName & "'.", _
vbCritical, "CopyActivesheet"
End If
End Sub

Copy all conditional formatting rules from one sheet to another

When I set up a new project I have a template sheet that I copy a specific range from. This pulls in the headers for a number of tables and their functions. However, the tables are scalable both across rows and down columns so I have a number of conditional formatting rules to ensure the data is presented in the right way as it scales.
The code I use to copy the sheet is as follows and I have it adjusting the widths of the columns automatically to ensure all the data is visible -
Sub CreateNewSheet(strNameOfSheetToCreate As String, strNameOfSheetToCreateAfter As String, strDefaultSheetToCreateAfter As String)
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim strCreateAfterSheetName As String
If Not IsTextEmpty(strNameOfSheetToCreateAfter) Then
strCreateAfterSheetName = strNameOfSheetToCreateAfter
Else
If Not IsTextEmpty(strDefaultSheetToCreateAfter) Then
strCreateAfterSheetName = strDefaultSheetToCreateAfter
End If
End If
' Only create sheet if sheet doesn't exist
If Not IsTextEmpty(strCreateAfterSheetName) Then
' Only create sheet if sheet doesn't exist
If Not WorkSheetExists(strNameOfSheetToCreate, wb) Then
If WorkSheetExists(strCreateAfterSheetName, wb) Then
wb.Sheets.Add(After:=wb.Sheets(strCreateAfterSheetName)).Name = strNameOfSheetToCreate
Else
wb.Sheets.Add.Name = strNameOfSheetToCreate
End If
' Update the list of sheets
ListSheets
End If
' Copy all cells including functions for specified range
wb.Worksheets("Project 1").Range("A1:I15").Copy wb.Worksheets(strNameOfSheetToCreate).Range("A1:I15")
' Fix Sheet Column widths to match the data
Dim SheetToModify As Worksheet
Set SheetToModify = wb.Worksheets(strNameOfSheetToCreate)
AutofitAllUsedColumns SheetToModify
End If
End Sub
Function WorkSheetExists(shtName As String, Optional wb As Workbook) As Boolean
Dim sht As Worksheet
If wb Is Nothing Then Set wb = ThisWorkbook
On Error Resume Next
Set sht = wb.Sheets(shtName)
On Error GoTo 0
WorkSheetExists = Not sht Is Nothing
End Function
Sub AutofitAllUsedColumns(ByVal mySheet As Worksheet)
mySheet.UsedRange.EntireColumn.AutoFit
End Sub
' Check if string is empty
Public Function IsTextEmpty(t As String)
If Trim(t & vbNullString) = "" Then
End If
End Function
The following are all the rules I'd like to copy to the new sheet. Any help to automate this on creating the new project sheet will be appreciated.

Match function in VBA gives compile error

I have a work book with two Worksheets. '2020-2021' Worksheet has some unique numbers in its Column D. Result of Match should come to 'Arrears' Worksheet. C2 cell in 'Arrears' has a number which I want to Match in Column D in 2020-2021. Entered the following code.
Range("C3").Value = WorksheetFunction.Match(Range("c2").value,Range('2020-2021'!d11:d206),0)
Gives Compile Error
Qualify (Use Variables)
If you feel like learning something, study the first two versions.
If not, pick one of the solutions in the third version.
Qualify; what does that even mean?
Related to this case, e.g. Range("C3") is not qualified. We don't know for sure where it refers to (belongs). It is short for ActiveSheet.Range("C3") which means that if we select Sheet1 it will refer to C3 on Sheet1, if we select Sheet2 it will refer to C3 on Sheet2 etc.
But if we use Worksheets("Sheet1").Range("C3") we have qualified the range and which ever worksheet we select, it will always refer to C3 on worksheet Sheet1 (Not 100% true because...).
Similarly to the range case, we are saying that the worksheet in Worksheets("Sheet1").Range("C3") is not qualified. The expression is actually short for ActiveWorkbook.Worksheets("Sheet1").Range("C3").
To qualify it, we can do Workbooks("Test.xlsm").Worksheets("Sheet1").Range("C3"). Now we are saying that the range is fully qualified, as is the worksheet. This might often seem unpractical, so ThisWorkbook 'comes to the rescue'.
If you need to refer to the workbook containing this code, just use ThisWorkbook. You don't care if it is called Test.xlsm or Last Years Official Inventory Report whatever.xlsm... just use ThisWorkbook.
Related to our case, we can then fully qualify our range using:
ThisWorkbook.Worksheets("Arrears").Range("C3")
Application.Match vs WorksheetFunction.Match
Sub qualifyAP()
' Define workbook.
Dim wb As Workbook
Set wb = ThisWorkbook ' The workbook containing this code.
' Define worksheets.
Dim src As Worksheet
Set src = wb.Worksheets("2020-2021")
Dim tgt As Worksheet
Set tgt = wb.Worksheets("Arrears")
' Use the Application version of Match.
Dim Result As Variant ' can hold any datatype incl. error value.
Result = Application.Match(tgt.Range("C2").Value, src.Range("D11:D206"), 0)
If Not IsError(Result) Then
tgt.Range("C3").Value = Result
'MsgBox "Data found and transferred."
Else
MsgBox "Data not found. Nothing done."
End If
End Sub
Sub qualifyWF()
' Define workbook.
Dim wb As Workbook
Set wb = ThisWorkbook ' The workbook containing this code.
' Define worksheets.
Dim src As Worksheet
Set src = wb.Worksheets("2020-2021")
Dim tgt As Worksheet
Set tgt = wb.Worksheets("Arrears")
' Use the WorksheetFunction version of Match.
On Error Resume Next
tgt.Range("C3").Value = WorksheetFunction.Match(tgt.Range("C2").Value, _
src.Range("D11:D206"), _
0)
If Err.Number = 0 Then
'MsgBox "Data found and transferred."
Else
MsgBox "Data not found. Nothing done."
End If
On Error GoTo 0
End Sub
Sub qualifyQF()
Worksheets("Arrears").Range("C3").Value = WorksheetFunction _
.Match(Worksheets("Arrears").Range("C2").Value, _
Worksheets("2020-2021").Range("D11:D206"), _
0)
' or:
With Worksheets("Arrears")
.Range("C3").Value = WorksheetFunction _
.Match(.Range("C2").Value, _
Worksheets("2020-2021").Range("D11:D206"), _
0)
End With
' or even:
With Worksheets("Arrears").Range("C3")
.Value = WorksheetFunction _
.Match(.Offset(-1).Value, _
Worksheets("2020-2021").Range("D11:D206"), _
0)
End With
End Sub

Excel - How to reset the default Table name when copying a sheet with a table

I have a workbook with one worksheet Sheet1. On that Sheet I have one table with its default name Table1.
When I copy the worksheet Right-Click > Move or Copy in the same workbook I get sheet Sheet1 (2).
The Table on this sheet is automatically named Table13.
I do some processing in that copied sheet and subsequently remove it. Leaving the workbook with only its original Sheet1.
Each time I make a copy of Sheet1 the table in the copied sheet is incremented by one.
Also if I remove the sheet and add a new one. It keeps incrementing.
I use the workbook and Sheet1 as a template and I create via a macro a lot of copies.
The new Table Name has now Incremented to Table21600.
I found out that Excel will give an overflow when I reach approximately Table21650.
So, I need a way to reset the Name counter of the added table.
Does anyone know how to achieve this?
You can access (and alter) the names of each table ("ListObject") from your macro-code as shown in this example:
Sub ListAllListObjectNames()
Dim wrksheet As Worksheet
Dim lstObjct As ListObject
Dim count As Integer
count = 0
For Each wrksheet In ActiveWorkbook.Worksheets
For Each lstObjct In wrksheet.ListObjects
count = count + 1
lstObjct.Name = "Table_" & CStr(count)
Debug.Print wrksheet.Name, ": ", lstObjct.Name
Next
Next
End Sub
Reset Table 'Counter'
Allthough the 'counter' will not stop incrementing, when you close
the workbook and open it the next time, it will again start from
Table13.
In the Immediate window CRTL+G you will see the table name
before and after the renaming. When done testing just out comment the
lines containing Debug.Print.
The First Code
' Copies a sheet and renames all its tables.
Sub CopySheetWithTable(Optional SheetNameOrIndex As Variant = "Sheet1", _
Optional NewTableName As String = "Tbl")
Dim MySheet As Worksheet
Dim MyCopy As Worksheet
Dim MyTable As ListObject
Dim i As Long
Set MySheet = ThisWorkbook.Worksheets(SheetNameOrIndex)
'MySheet.Copy MySheet ' Before e.g. Sheet1)
MySheet.Copy , MySheet ' After e.g. Sheet1
Set MyCopy = ActiveSheet
For Each MyTable In MyCopy.ListObjects
i = i + 1
Debug.Print "Old Table Name = " & MyTable.Name
MyTable.Name = NewTableName & i
Debug.Print "Old Table Name = " & MyTable.Name
Next
End Sub
Usage
Copy the previous and the following sub into a module. Run the
following sub to copy a new worksheet. Adjust if you want it before
or after the sheet to be copied.
You don't need to copy the worksheet manually anymore.
The Second Code
' You can create a button on the worksheet and use this one-liner in its code.
Sub CopySheet()
CopySheetWithTable ' Default is CopySheetWithTable "Sheet1", "Tbl"
End Sub
Delete all Sheets After Worksheet
This is just a testing tool.
' Deletes all sheets after the selected sheet (referring to the tab order).
Sub DeleteSheetsAfter(DeleteAfterSheetNameOrIndex As Variant) 'Not tested.
Dim LastSheetNumber As Long
Dim SheetsArray() As Variant
Dim i As Long
' Try to find the worksheet in the workbook containing this code.
On Error Resume Next
LastSheetNumber = _
ThisWorkbook.Worksheets(DeleteAfterSheetNameOrIndex).Index
If Err.Number <> 0 Then
MsgBox "There is no Sheet '" & DeleteAfterSheetNameOrIndex & "' " _
& "in (this) workbook '" & ThisWorkbook.Name & "'."
Exit Sub
End If
With ThisWorkbook
ReDim SheetsArray(.Sheets.Count - LastSheetNumber - 1)
For i = LastSheetNumber + 1 To .Sheets.Count
SheetsArray(i - LastSheetNumber - 1) = i
Next
End With
Application.DisplayAlerts = False
ThisWorkbook.Sheets(SheetsArray).Delete
Application.DisplayAlerts = True
MsgBox "Deleted " & UBound(SheetsArray) & " worksheets after worksheet '" _
& ThisWorkbook.Worksheets(DeleteAfterSheetNameOrIndex).Name & "'.", _
vbInformation, "Delete Successful"
End Sub
Sub DeleteAfter()
DeleteSheetsAfter "Sheet1"
End Sub

Insert user defined string into formula

I duplicate a report and rename the tab as per user input.
I need to take that user input and insert it into a formula which would then be placed into a cell. Over time (monthly) the formula would need to change columns.
Below is what I have done so far.
sName is the user defined input, I think I have declared it as a global variable correctly
sName is used in SPVCLookup as the name of the tab (not working)
sName is used in countif as part of a formula (not working)
' will copy SPC Report to new tab and ask user to name the tab
Dim sName As String
Sub CopyRename()
'Dim sName As String
Dim wks As Worksheet
Worksheets("SPC Report").Copy after:=Sheets(Worksheets.Count)
Set wks = ActiveSheet
Do While sName <> wks.Name
sName = Application.InputBox _
(Prompt:="Enter new worksheet name")
On Error Resume Next
wks.Name = sName
On Error GoTo 0
Loop
Set wks = Nothing
End Sub
'------------------------
Sub CreateDA()
Dim ws As Worksheet
With ThisWorkbook
Set ws = .Sheets.Add(After:=.Sheets(.Sheets.Count))
ws.Name = "Departmental Analysis"
End With
End Sub
'------------------------
Sub SPCVlookup()
'Sheets("sName").Select 'this needs to be user defined
Range(Range("E2"), Range("E2").End(xlDown)).Formula = "=VLOOKUP(D2,'Card Exchange'!$A$1:$V$218,6,FALSE)"
End Sub
Sub Countif()
Sheets("Departmental Analysis").Select
' I think I need a for loop to cycle through the range columns
Range(Range("E2"), Range("E2").End(xlDown)).Formula = "=COUNTIFS('sname'!$A$1:$E$12104,A3)"
End Sub
You've got two problems here.
Sub SPCVlookup()
Sheets("sName").Select 'selects the sheet called "sName"
Range(Range("E2"), Range("E2").End(xlDown)).Formula = "=VLOOKUP(D2,'Card Exchange'!$A$1:$V$218,6,FALSE)"
End Sub
This code selects the sheet called "sName". Remove the "" marks:
Sub SPCVlookup()
Sheets("sName").Select 'selects the sheet called "sName"
Range(Range("E2"), Range("E2").End(xlDown)).Formula = "=VLOOKUP(D2,'Card Exchange'!$A$1:$V$218,6,FALSE)"
End Sub
Range(Range("E2"), Range("E2").End(xlDown)).Formula = "=COUNTIFS('sname'!$A$1:$E$12104,A3)"
This is a bit trickier. You'll need to copy sName into the formula, but in order to do so you'll need to escape it (just in case sName contains quotes). You can do that by doubling each quote:
Replace(sName, """", """"&"""")
So...
Range(Range("E2"), Range("E2").End(xlDown)).Formula = "=COUNTIFS('" & Replace(sName, """", """"&"""") & "'!$A$1:$E$12104,A3)"
This won't update the cells when sName changes; to do that, you'll need to set a spreadsheet name. Variables in VBA and Formulas aren't shared.

Resources