VBA rename sheets based on Inputbox cell value - vba

I would like to rename sheets based on the same cell within each sheet. When i run the macro rather than having the cell predefined I would like to use an input box to define what cell the sheets are to be named after. This is what I have so far- currently it works for only cell C8.
Sub RenameSheet()
Dim ws As Worksheet
For Each ws In Worksheets
On Error Resume Next
If Len(ws.Range("C8")) > 0 Then
ws.Name = ws.Range("C8").Value
End If
On Error GoTo 0
If ws.Name <> ws.Range("C8").Value Then
MsgBox ws.Name & " Was Not renamed, the suggested name was invalid"
End If
Next
End Sub
I think this code would help but I cannot get it to run
Set CellID = Application.InputBox("Cell reference to label sheets", Type:=8)
Anyone have help on this?

I suggest the following changes.
Also it would be a good idea to activate the current sheet so the user always automatically selects a cell on the correct sheet.
Option Explicit
Public Sub RenameSheet()
Dim ws As Worksheet
For Each ws In Worksheets
ws.Activate 'so we automatically are on the correct sheet to select a range
Dim CellID As Range
Set CellID = Application.InputBox("Cell reference to label sheets", Type:=8)
If CellID.Count > 1 Then 'check how many cells were selected
MsgBox "Please select only one cell!", vbExclamation
Exit Sub
End If
If Len(CellID.Value) > 0 Then
On Error Resume Next
ws.Name = CellID.Value
'catch the error
If Err.Number <> 0 Then MsgBox ws.Name & " Was Not renamed, the suggested name was invalid"
On Error GoTo 0
Else
MsgBox ws.Name & " Was Not renamed, the suggested name was empty"
End If
Next ws
End Sub
Alternative to select the address once and use the same address on every worksheet.
Option Explicit
Public Sub RenameSheet()
Dim CellID As Range
Set CellID = Application.InputBox("Cell reference to label sheets", Type:=8)
If CellID.Count > 1 Then 'check how many cells were selected
MsgBox "Please select only one cell!", vbExclamation
Exit Sub
End If
Dim NameAddress As String
NameAddress = CellID.Address(External:=False)
Dim ws As Worksheet
For Each ws In Worksheets
If Len(ws.Range(NameAddress).Value) > 0 Then
On Error Resume Next
ws.Name = ws.Range(NameAddress).Value
If Err.Number <> 0 Then MsgBox ws.Name & " Was Not renamed, the suggested name was invalid"
On Error GoTo 0
Else
MsgBox ws.Name & " Was Not renamed, the suggested name was empty"
End If
Next ws
End Sub

This should work for you:
Sub RenameSheet()
Dim ws As Worksheet, CellID As Range
For Each ws In ThisWorkbook.Worksheets
Set CellID = Application.InputBox("Cell reference to label sheets", Type:=8)
Set CellID = ws.Cells(CellID.Row, CellID.Column)
On Error Resume Next
ws.Name = CellID
On Error GoTo 0
If ws.Name <> CellID.Value Then
MsgBox ws.Name & " Was Not renamed, the suggested name was invalid"
End If
Next
End Sub
This code will set your range twice, because the inputbox assumes ActiveSheet, as there's no way to assign the worksheet name to your input range without typing it out.
Therefore, once you type in the cell address, it will utilize the .Row and .Column properties of the inputrange of the activesheet, while assigning them to the correct worksheet since we didn't qualify the worksheet in CellID.Row and CellID.Column.

Related

Find cell containing greater 255 characters

My code below works perfectly to find a cell on a different worksheet when the string is small, however large text strings pull up an error. I have tried using error handling even just to give a MsgBox rather than open a VBA window when it errors.
Can anyone help, preferably find the cell with many characters or if not possible, put an error handler in to say something like, too large to search.
What the code does, is a have a range of cells with text in each cell. I can click on that cell, or a cell 2 columns to the right, then click the FIND button, to go in the next worksheet to find the exact same cell value. All cells are unique.
Sub Find_Cell()
Dim NA As Worksheet
Set NA = Worksheets("Notes Analysis")
LastRow = NA.Cells(Rows.Count, 2).End(xlUp).Row
On Error Resume Next
If Not Intersect(ActiveCell, Range("G19:G" & LastRow)) Is Nothing Then
Dim value As String 'Declare a string
value = ActiveCell.Offset(, -2) 'Get the value of the selected Cell
Dim ws As Worksheet
'ws is the worksheet from we are searching the value
'You have to change myWorkSheetName for you worksheet name
Set ws = ThisWorkbook.Worksheets("DEBT_SALE_ACTIVITY")
ws.Activate
Dim c As Range 'Declare a cell
Set c = ws.Cells.Find(value, LookIn:=xlValues) 'Search the value
If Not c Is Nothing Then 'If value found
c.Activate 'Activate the cell, select it
Else
MsgBox "Not found" 'shows a message "Not Found"
End If
Else
If Not Intersect(ActiveCell, Range("E19:E" & LastRow)) Is Nothing Then
Dim value2 As String 'Declare a string
value2 = ActiveCell 'Get the value of the selected Cell
Dim ws2 As Worksheet
'ws is the worksheet from we are searching the value
'You have to change myWorkSheetName for you worksheet name
Set ws2 = ThisWorkbook.Worksheets("DEBT_SALE_ACTIVITY")
ws2.Activate
Dim c2 As Range 'Declare a cell
Set c2 = ws2.Cells.Find(value2, LookIn:=xlValues) 'Search the value
If Not c2 Is Nothing Then 'If value found
c2.Activate 'Activate the cell, select it
Else
MsgBox "Not found" 'shows a message "Not Found"
End If
Else
MsgBox "Select an Account Note"
End If 'end the If for if active cell is in our notes
End If 'end the If for if active cell is in Account note
End Sub
To provide an error message indicating the text is too long you could do the following:
Add this after each statement where you assign value its value:
value = ActiveCell.Offset(, -2) 'Get the value of the selected Cell
If Len(value) > 255 Then
MsgBox "Text in cell " & CStr(ActiveCell.Address) & " is too long", vbOKOnly, "Search Text Too Long"
Exit Sub
End If
Also, you might want to change your if...then...else code structure.
Currently your code is operating like this:
If Not Intersect(ActiveCell, Range("G19:G" & LastRow)) Is Nothing Then
do things
exit sub
Else
If Not Intersect(ActiveCell, Range("E19:E" & LastRow)) Is Nothing Then
do things
exit sub
Else
MsgBox "Select an Account Note"
exit sub
Which, based on your comments for your End If's isn't exactly what your message box says. If your first if statement is Account Notes and your second if statement is notes, then a better structure would be the following.
Change this code
Else
If Not Intersect(ActiveCell, Range("E19:E" & LastRow)) Is Nothing Then
To look like this
ElseIf Not Intersect(ActiveCell, Range("E19:E" & LastRow)) Is Nothing Then
Then the statement `MsgBox "Select an Account Note" will be accurate. You also be able to delete one of your End If statements.
Your code will operate like this:
If Not Intersect(ActiveCell, Range("G19:G" & LastRow)) Is Nothing Then
do things
exit sub
ElseIf Not Intersect(ActiveCell, Range("E19:E" & LastRow)) Is Nothing Then
do things
exit sub
Else
MsgBox "Select an Account Note"
exit sub

Rename Excel Sheet with VBA Macro

I want to ask about rename the excel sheet, i want to rename the sheet with new name : older name + _v1.
So if my current sheet name is test, then I want the new name test_v1.
I only know the standard vba for rename excel sheet which is renaming excel sheet by the sheet content.
Sub Test()
Dim WS As Worksheet
For Each WS In Sheets
WS.Name = WS.Range("A5")
Next WS
End Sub
The "no frills" options are as follows:
ActiveSheet.Name = "New Name"
and
Sheets("Sheet2").Name = "New Name"
You can also check out recording macros and seeing what code it gives you, it's a great way to start learning some of the more vanilla functions.
This should do it:
WS.Name = WS.Name & "_v1"
Suggest you add handling to test if any of the sheets to be renamed already exist:
Sub Test()
Dim ws As Worksheet
Dim ws1 As Worksheet
Dim strErr As String
On Error Resume Next
For Each ws In ActiveWorkbook.Sheets
Set ws1 = Sheets(ws.Name & "_v1")
If ws1 Is Nothing Then
ws.Name = ws.Name & "_v1"
Else
strErr = strErr & ws.Name & "_v1" & vbNewLine
End If
Set ws1 = Nothing
Next
On Error GoTo 0
If Len(strErr) > 0 Then MsgBox strErr, vbOKOnly, "these sheets already existed"
End Sub

excel to create a new sheet for each row

The Data
Sheet one will be for data entry. Each row will represent a Service Ticket. Each column will represent data about the service incident such as serial number or model number.
Desired Result
For each row containing data in a particular field (Column A ~ "Ticket Number) Excel will create a new sheet (The service ticket) based on a template and place the data from the corresponding row into the designated cells.
Thank you in advance for any assistance you may be able to provide.
I'll start by saying that you should be careful with this as there is a limit to the number of sheets in a workbook. But here is some code in vb. It should give you the logic to get it done in vba. There will just be some difference in referring to the sheet and maybe cells.
You will need to declare the worksheet that you are reading through
Dim ws As Excel.Worksheet
Set ws = ea.Worksheets(1)
It may start at sheet index 0 so Set ws = ea.Worksheets(0)
Or there is something like Excel.Application.Activsheet
Here is the logic to loop through the rows and check the value of column A.
dim lRow as integer
Do While lRow <= ws.UsedRange.Rows.Count
If ws.Range("A" & lRow).Value <> "" Then Then
'If cell A is not blank we then call the worksheet add function.
'Pass the name you want the worksheet and the page setup arguments.
WorksheetAdd ws.Range("A" & lRow).Value, xlPaperLetter, xlPortrait
ws.name = ws.Range("A" & lRow).Value
End If
lRow = lRow + 1
ws.Range("A" & lRow).Activate
Loop
You will want a worksheetAdd function like this
Private Sub WorksheetAdd(szJobNumber As String, Papersize As XlPaperSize, PageOrientation As XlPageOrientation)
Dim bDisplayAlerts As Boolean
On Error GoTo ErrorHandler
'Add worksheet to workbook.
Set ws = ea.Worksheets.Add
ws.Name = szJobNumber
With ws.PageSetup
.Orientation = PageOrientation
.LeftFooter = "&D"
.CenterFooter = "&A"
.RightFooter = "Page &P of &N"
.Papersize = Papersize
End With
On Error GoTo 0
Exit Sub
ErrorHandler:
If Err.Number = 1004 Then
If MsgBox("There has been an error(#1004). Contact support. Excel is not installed or produced an error. Also, check for default printer.",vbCritical, "Information") = vbOK Then
'Unload frmPTReports
Exit Sub
End If
Else
Err.Raise Err.Number, Err.Source, Err.Description
End If
End Sub

Type mismatch on query to create an array from list

I am running some VBa code in Excel to update multiple sheets, based on a list of sheets names.
Sub Test()
Dim ArrayOne As Variant
ArrayOne = ActiveSheet.Range("A8:A10")
Dim sheetsArray As Sheets
Set sheetsArray = ActiveWorkbook.Sheets(ArrayOne)
Dim target As Range
Dim sheetObject As Worksheet
' change value of range 'a1' on each sheet from sheetsArray
For Each sheetObject In sheetsArray
Set target = sheetObject.Range("A1")
target.Value = "Test"
Next sheetObject
End Sub
Here is my code, unfortuantly it errors: Type Mismatch on the following line of code
Set sheetsArray = ActiveWorkbook.Sheets(ArrayOne)
I'm understanding that you want to update the same cells in each worksheet, based on a list of worksheets that is contained in an Excel Range (A8:A10).
Try the following code:
Public Sub test()
Dim wks As Worksheet
Dim WksCell As Range
' Turn on inline Error Handling
On Error Resume Next
' Look at each cell within the range and obtain worksheet names
For Each WksCell In ActiveSheet.Range("A8:A10").Cells
' Attempt to reference the worksheet using this name
Set wks = Excel.Worksheets(WksCell.Value)
' Check if a "SubScript out of range" error occurred
' If so, it indicates that the sheet name does not exist
If Err.Number = 9 Then
' Set its style to Bad and move on
WksCell.Style = "Bad"
Err.Clear
Else
' For each worksheet, execute our logic
wks.Range("A1").Value = "Testing"
End If
' If any other error occurred, report it to the user and exit
If Err.Number <> 0 And Err.Number <> 9 Then
MsgBox "An error has occurred. Error #" & Err.Number & vbCr & _
Err.Description, vbCritical, "Error Encountered"
Set wks = Nothing
Exit For
End If
Next
' Return to normal error handling
On Error GoTo 0
Set wks = Nothing
End Sub
If you'd rather use it in a Macro then you can change the line
For Each WksCell In ActiveSheet.Range("A8:A10").Cells
to
For Each WksCell In Excel.Selection
which will use your current selection as the Worksheet list. Makes it more dynamic.
Hope that helps.

VBA Code to cycle through worksheets starting with a specific sheet (index 3)

I need to cycle through sheets of index 3 tip last sheet and run a code. I tried something like this but its doesn't work.
If (ws.sheetIndex > 2) Then
With ws
'code goes here
End With
End If
I did a search but don't find a solution to this problem. Help would be much appreciated.
I also tried:
Dim i As Long, lr As Long
Dim ws As Worksheet
Windows("Book1").Activate
With ActiveWorkbook
Set ws = .Worksheets("index")
For i = 3 To 10
'code goes here
Next i
End With
You can try the following, which iterates over all worksheets in your workbook and only "acts" for worksheets with index 3 or above.
Dim sheet As Worksheet
For Each sheet In ActiveWorkbook.Worksheets
If sheet.Index > 2 Then
' Do your thing with each "sheet" object, e.g.:
sheet.Cells(1, 1).Value = "hi"
End If
Next
Note that this doesn't put a hard limit on the number of sheets you have (10 or whatever), as it will work with any number of worksheets in your active workbook.
EDIT
If you want the code to run on worksheets with names "Sheet" + i (where i is an index number from 3 onwards), then the following should help:
Dim sheet As Worksheet
Dim i As Long
For i = 3 To ActiveWorkbook.Worksheets.Count
Set sheet = ActiveWorkbook.Worksheets(i)
If sheet.Name = "Sheet" & i Then
' Do your thing with each "sheet" object, e.g.:
sheet.Cells(2, 2).Value = "hi"
End If
Next i
Of course, this means that the names of your worksheets need to always follow this pattern, so it's not best practice. However, if you're sure the names are going to stay like this, then it should work well for you.
Try excluding first and second sheet using name:
Public Sub Sheets3andUp()
Dim ws As Worksheet
Dim nameOfSheet1 As String
Dim nameOfSheet2 As String
nameOfSheet1 = "Sheet1"
nameOfSheet2 = "Sheet2"
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> nameOfSheet1 And ws.Name <> nameOfSheet2 Then
'Code goes here
Debug.Print ws.Name
End If
Next ws
End Sub
Note that the user can reorder the sheets in the Worksheets Collection, so it is better to refer to the sheets by CodeName (which the user cannot change), and exclude by CodeName the sheets to be skipped, as here:
Public Sub TestLoop()
On Error GoTo ErrHandler
Dim ws As Worksheet, s As String
For Each ws In Worksheets
If ws.CodeName <> "Sheet2" Then
s = s & vbNewLine & ws.CodeName
End If
Next ws
s = "WorksheetList (except Sheet2:" & vbNewLine & vbNewLine & s
MsgBox s, vbOKOnly, "Test"
EndSUb:
Exit Sub
ErrHandler:
Resume EndSUb
End Sub
If I drag Sheet 3 to precede Sheet1, the MsgBox outputs:
WorksheetList (except Sheet2:
Sheet3
Sheet1