Automatically rename tabs - excel

The script below loops through to create tabs and name the tab then it will place the tab name in cell B3. It's been working fine but now gives the catch all runtime error 1004. At the bottom of my script it renames the tab. This is where the error is happening. It's creating the tabs but fails to rename it. Can anyone please suggest another way to rename the tab in this script. The error is on Sheets(Name).Select.
Public Sub CreateTabs()
Sheets("TABlist").Select
' Determine how many Names are on Data sheet
FinalRow = Range("A65000").End(xlUp).Row
' Loop through each Name on the data sheet
For x = 1 To FinalRow
LastSheet = Sheets.Count
Sheets("TABlist").Select
Name = Range("A" & x).Value
' Make a copy of FocusAreas and move to end
Sheets("TABshell").Copy After:=Sheets(LastSheet)
' rename the sheet and put name in Cell B2
Sheets(LastSheet + 1).Name = Name
Sheets(Name).Select
Range("B3").Value = Name
Next x
End Sub

It is very important to write code that is robust. It shouldn't fail in any scenario. For example appropriate error handling should be done and variables declared.
I would recommend reading this.
Topic: To ‘Err’ is Human
Link: http://www.siddharthrout.com/2011/08/01/to-err-is-human/
Now back to your code. I have amended the code. Try this. I have also commented the code so you shouldn't have any difficulty understanding it :) Still if you do, just give a shout.
Code
Option Explicit
Public Sub CreateTabs()
Dim ws As Worksheet
Dim FinalRow As Long, x As Long, LastSheet As Long
Dim name As String
On Error GoTo Whoa
Application.ScreenUpdating = False
Set ws = Sheets("TABlist")
FinalRow = ws.Range("A" & Rows.Count).End(xlUp).Row
For x = 1 To FinalRow
LastSheet = Sheets.Count
'~~> Get the name for the new sheet
name = ws.Range("A" & x).Value
'~~> Check if you already have a sheet with that name or not
If Not SheetExists(name) Then
Sheets("TABshell").Copy After:=Sheets(LastSheet)
ActiveSheet.name = name
Range("B3").Value = name
End If
Next x
LetsContinue:
Application.ScreenUpdating = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
'~~> Function to check if sheet exists
Function SheetExists(wst As String) As Boolean
Dim oSheet As Worksheet
On Error Resume Next
Set oSheet = Sheets(wst)
On Error GoTo 0
If Not oSheet Is Nothing Then SheetExists = True
End Function

Each worksheet name in an Excel workbook needs to be unique.
As a quick fix to see what name is causing the error, try using this code and then check the sheet names against your list.
Public Sub CreateTabs()
On Error Resume Next
Sheets("TABlist").Select
' Determine how many Names are on Data sheet
FinalRow = Range("A65000").End(xlUp).Row
' Loop through each Name on the data sheet
For x = 1 To FinalRow
LastSheet = Sheets.Count
Sheets("TABlist").Select
Name = Range("A" & x).Value
' Make a copy of FocusAreas and move to end
Sheets("TABshell").Copy After:=Sheets(LastSheet)
' rename the sheet and put name in Cell B2
Sheets(LastSheet + 1).Name = Name
Sheets(Name).Select
Range("B3").Value = Name
Next x
On Error GoTo 0
End Sub

I got lost amid all the selects so I am not sure why your original code failed. I edited your question to make it more readable but only I can see the improvement until my edit it peer reviewed.
I have deleted all your select statements. Comments starting '## explain why I have made other changes.
Option Explicit
Public Sub CreateTabs()
Dim CrntRow As Long '## I like names I understand
Dim FinalRow As Long
Dim Name As String
' Determine how many Names are on Data sheet
'## Row.Count will work for any version of Excel
FinalRow = Sheets("TABlist").Cells(Rows.Count, "A").End(xlUp).Row
' Loop through each Name on the data sheet
For CrntRow = 1 To FinalRow
Name = Sheets("TABlist").Range("A" & CrntRow).Value
' Make a copy of FocusAreas and move to end
Sheets("TABshell").Copy After:=Sheets(Worksheets.Count)
' rename the sheet and put name in Cell B2
'## The copy will be the active sheet
With ActiveSheet
.Name = Name
.Range("B3").Value = Name
End With
Next CrntRow
End Sub

Related

VBA - Unable to Set Worksheet Variable

I'm new to VBA but I'm not new to scripting languages. I have a problem with setting a worksheet variable for some reason in this routine. The same syntax works in other routines but for some reason it won't in this one.
Can someone explain why my worksheet variable 'wks' will NOT populate? I'm not getting any errors but it will not populate. It remains empty.
The problem is this line "Set wks = .Sheets(strTemplate)". The variable 'strTemplate', when mousing over it DOES indicate the proper template sheet name but the worksheet variable 'wks' never populates.
Here's the subroutine that creates a copy of a template sheet, then renames it in order to be populated with data from the 'Main' sheet. I even put in 'Debug' commands but the one that prints "Sheet =" never executes due to 'wks' being empty.
' REPLACE MAIN WORKSHEET AFTER COPYING
'
Public Sub SheetReplace(strSheetName As String, strTemplate As String)
Dim wks As Worksheet
Debug.Print "Entered SheetReplace"
' We don't want screen updating
Application.ScreenUpdating = False
' Delete the existing Main - Copy if it exists
Application.DisplayAlerts = False 'turn off alerts
On Error Resume Next 'continue execution
Worksheets("Main - Copy").Delete 'delete the worksheet
Err.Clear 'clear error
Application.DisplayAlerts = True 'turn on alerts
With ThisWorkbook
' Duplicate the Main - Tmplt sheet
' Duplicate the template sheet
Set wks = .Sheets(strTemplate)
Debug.Print "Sheet = [" & wks & "]"
' Check sheet visibility
isVisible = (wks.Visible = xlSheetVisible)
' Make the sheet visible if not
If Not isVisible Then wks.Visible = xlSheetVisible
' Copy duplicate to the end of the sheets
wks.Copy After:=.Sheets(strSheetName)
' Change the name of the sheet
ActiveSheet.Name = strSheetName & " - Copy"
' Make the sheet invisible
If isVisible Then ws.Visible = xlSheetHidden
' BEGIN COPYING MAIN SHEET INFO
With Worksheets("Main")
Set srcWorkSheet = Worksheets(ActiveSheet.Name) ' Duplicate the Copy name
lastRowMain = .Cells(.Rows.Count, "A").End(xlUp).Row ' Find the last row used in "Main" sheet
' Copy the ranges that contain daily data.
' Copy the Month
.Range("$C$8").Copy Destination:=Worksheets(ActiveSheet.Name).Range("$C$8")
.Range("$I$11").Copy Destination:=Worksheets(ActiveSheet.Name).Range("$I$11")
.Range("$B15:$I51").Copy Destination:=Worksheets(ActiveSheet.Name).Range("$B15:$I51")
srcWorkSheet.Visible = xlSheetHidden ' Make the copy sheet invisible
' Clear cells (including formatting)
.Range("$C15:$H51").ClearContents
End With
' THIS IS THE END OF THE MAIN COPY
End With
End Sub
Any info would be appreciated. Thanks.
Well apparently I had a syntax error & the 'wks' variable WAS being set, I just needed to reference the 'wks.Name' property. Once I did that the execution continued.
Set wks = .Sheets(strTemplate)
Debug.Print "Sheet = [" & wks.Name & "]" <------ OUTPUT: Sheet = [Main - Copy]
#VBasic2008 : Yep. I didn't see your post until now but thanks for responding with that. You've all been a great help.
Update Workbook
Use Option Explicit.
Use ThisWorkbook if you're doing stuff in the workbook containing the code.
On Error Goto 0 turns off error handling (This was the fatal mistake).
A Quick Fix
Option Explicit
Public Sub SheetReplace(strSheetName As String, strTemplate As String)
Dim wb As Workbook
Set wb = ThisWorkbook
' We don't want screen updating
Application.ScreenUpdating = False
' Delete the existing Main - Copy if it exists
On Error Resume Next 'continue execution
Application.DisplayAlerts = False 'turn off alerts
wb.Worksheets("Main - Copy").Delete 'delete the worksheet
Application.DisplayAlerts = True 'turn on alerts
On Error GoTo 0 'disable error handling
' Duplicate the Main - Tmplt sheet
' Duplicate the template sheet
Dim wks As Worksheet
Set wks = wb.Worksheets(strTemplate)
' Check sheet visibility
Dim isVisible As Boolean
isVisible = (wks.Visible = xlSheetVisible)
' Make the sheet visible if not
If Not isVisible Then
wks.Visible = xlSheetVisible
End If
' Copy duplicate to the end of the sheets
wks.Copy After:=wb.Worksheets(strSheetName)
' Change the name of the sheet
Dim src As Worksheet
Set src = wb.ActiveSheet
src.Name = strSheetName & " - Copy"
' Make the sheet invisible
If isVisible Then wks.Visible = xlSheetHidden
' BEGIN COPYING MAIN SHEET INFO
Dim LastRowMain As Long
With wb.Worksheets("Main")
' Find the last row used in "Main" sheet
LastRowMain = .Cells(.Rows.Count, "A").End(xlUp).Row
' Copy the ranges that contain daily data.
' Copy the Month
.Range("$C$8").Copy Destination:=src.Range("$C$8")
.Range("$I$11").Copy Destination:=src.Range("$I$11")
.Range("$B15:$I51").Copy Destination:=src.Range("$B15:$I51")
' If you only need values, this is more efficient (faster).
'src.Range("$C$8").Value = .Range("$C$8").Value
'src.Range("$I$11").Value = .Range("$I$11").Value
'src.Range("$B15:$I51").Value = .Range("$B15:$I51").Value
' Make the copy sheet invisible
src.Visible = xlSheetHidden
' Clear cells (including formatting)
.Range("$C15:$H51").ClearContents
End With
' THIS IS THE END OF THE MAIN COPY
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

Why do I get object required error for the below VBA code?

I am new to VBA, I need help applying the below VBA code to two specific work sheets by Region and by Model. The code simply finds the last column which has the name total for the year and copies the previous months values into a new column. But I get an error object required at ws.
Sub Insert_New_Col()
Dim Found As Range, BeforeR As Long
Dim xSheets As Variant
Dim ws As Worksheet
Dim i As Long
xSheets = Array("By Region", "By Model") '
For i = LBound(xSheets) To UBound(xSheets)
Set ws = xSheets(i)
Set Found = ws.Rows(3).Find(What:="Total for the Year", Lookat:=xlWhole)
BeforeR = R.Column - 1
If Found Is Nothing Then
MsgBox ("The word 'Totals' was not found in Row 5 on Sheet: " & ws.Name)
Else
Columns(BeforeR).Copy
ws.Columns(R.Column).Insert Shift:=xlRight
End If
Next i
End Sub
You want an actual member of the Worksheets collection:
Set ws = ThisWorkbook.Worksheets(xSheets(i))
BeforeR = R.Column - 1
What is R? Add Option Explicit to the top of the module and declare all variables.

Excel wont rename sheet with vba code

I am trying to copy sheet1 of workbook name Source.xlsm to workbook name s.xlsx. And then rename the copied sheet to a column value say D1.
My code copies the sheet properly but while renaming it is giving error.
Instead of displaying message name already exits it is going to else part and giving error: Run-time error '1004': Can not rename a sheet to name as of another sheet. And this line Sheet.Name = range("D1") is highlighted.
Plese correct me what i am doing wrong.
My Code is:
Sub savesheet()
Dim sPath As String
Dim wbPath1 As Workbook
Dim wsName As String
sPath = Application.ActiveWorkbook.Path & "\s\s.xlsx"
Set wbPath1 = Workbooks.Open(sPath)
Workbooks("Source.xlsm").Sheets("Sheet1").Copy After:=wbPath1.Sheets(1)
'For Each Sheet In ActiveWorkbook.Sheets
For Each Sheet In Workbooks("s.xlsx").Sheets
If Sheet.Name = range("D1") Then
MsgBox "name already exits"
Exit Sub
Else
Sheet.Name = range("D1")
End If
Next
End Sub
Changed the code and issues resolved. Below is the code for reference:
Sub movesheet3()
Dim name As String
Dim sPath As String
Dim wbPath1 As Workbook
name = Workbooks("Source.xlsm").Sheets("Sheet1").range("D1").value
sPath = Application.ActiveWorkbook.Path & "\s\s.xlsx"
Set wbPath1 = Workbooks.Open(sPath)
wbPath1.Activate
'Workbooks("Source.xlsm").Sheets("Sheet1").Copy After:=wbPath1.Sheets(Sheets.Count)
For i = 1 To (Worksheets.Count)
If ActiveWorkbook.Sheets(i).name = name Then
MsgBox "Sheet name already exist. GO back to the sheet and enter valid name in D1 cell"
Exit Sub
End If
Next
Workbooks("Source.xlsm").Sheets("Sheet1").Copy After:=wbPath1.Sheets(Sheets.Count)
Sheets(ActiveSheet.name).name = name
ActiveWorkbook.Close True
End Sub
Thanks for the help everyone....Cheers

Creating new sheets and renaming them in a loop

I am using Excel 2013. I have the macro that adds a new sheet and renames it. But when I run the macro for the second time, it throws an error because there is a sheet with the name that was just created. For example, I create a sheet and name it Account, the next time when I run the macro I want it to be Account1 and next time Account2 and so on.
Without seeing the rest of your code, see below, which assumes you want to create 10 new tabs, starting with Account1, and ending with Account10. It works by using the counter variable to count down from 10, and each time it creates the new tab, it simply appends the counter's value to "Account" for the sheetname.
Sub Sheet_Creation()
Dim counter As Integer
For counter = 10 To 1 Step -1
Sheets.Add.Name = "Account" & counter
Next counter
End Sub
This procedure will add a new worksheet and name it properly:
Sub AddWS()
Const WS_NAME = "Account"
Dim c
On Error Resume Next
With Sheets.Add(, ActiveSheet)
Do
.Name = WS_NAME & c
If Err = 1004 Then
c = c + 1
Err.Clear
Else
Exit Do
End If
DoEvents
Loop
End With
End Sub
Note: you can manage the base name applied to the newly created worksheet by editing the first line.
UPDATE
Based on your new requirement to be able to access the newest worksheet created at a later point by using the base name ('Account' in your question), please use this version of the above procedure:
Sub AddWS()
Const WS_NAME = "Account"
Dim c
On Error Resume Next
With Sheets.Add(, ActiveSheet)
Do
.Name = WS_NAME & c
If Err = 1004 Then
c = c + 1
Err.Clear
Else
Exit Do
End If
DoEvents
Loop
ThisWorkbook.Names.Add "Newest_" & WS_NAME, .Name
End With
End Sub
Now, later on when you wish to select that sheet, you can use this code:
Sheets([Newest_Account]).Select
Private Sub CreateSheet()
Dim ws As Worksheet
With ActiveWorkbook
Set ws = .Sheets.Add(After:=.Sheets(.Sheets.Count))
ws.Name = "Account" & Worksheets.Count
End With
End Sub
The above macro will create new sheets named Account#, with # = the total number of sheets.

Resources