vba create a new sheet and change name - vba

I am a VBA new user. My purpose is copy a existing worksheet to a new one. And then change the new worksheet name to a proper name. However, I got the VBA Error Message like,
vba runtime error 9 subscript out of range(at the line Set new_ws =Active...)
The VBA code will be the following; thanks in advance
Sub CreateWS()
Dim ws As Worksheet
Dim new_ws As Worksheet
Set ws = ActiveWorkbook.Worksheets("Bus Voltage")
ws.Name = "Bus Voltage_All"
ws.Copy Worksheets(Sheets.Count)
Set new_ws = ActiveWorkbook.Worksheets("Bus Voltage_All(2)")
new_ws.Name = "Bus Voltage"
End Sub

It looks to me like you have an issue with a space.
Your line Set new_ws = ActiveWorkbook.Worksheets("Bus Voltage_All(2)")
Should be
Set new_ws = ActiveWorkbook.Worksheets("Bus Voltage_All (2)")
Notice the space after _All? You were missing that in your code.
A (potentially) helpful tidbit is that when you use the .Copy method, your new worksheet is automatically activated, so you can use this code instead (to avoid errors with the space):
ws.Copy Worksheets(Sheets.Count)
Set new_ws = ActiveSheet
And, on the topic of referencing sheets at all (though not directly related to your question), you can use something called the CodeName to reference the sheet.
For example:
The CodeNames are Sheet1, Sheet2, etc.
The code:
Worksheets("Old Data").Activate
And
Sheet1.Activate
are equivalent.
The major benefit to referencing sheets this way is that if your worksheet name changes, your code won't break.

Related

Create another sheet if only 1 exists and use it VBA

I had a working program that uses Sheet1 and Sheet2 in the code. However, now I realized that if I remove Sheet2 and create new sheet that sheet number is no longer being used. What I actually need to do is to create another sheet if only 1 exists and then use that in my code. However, my trials have not worked so far. I used to have code like this to define variables:
Dim datasheet As Worksheet
Dim reportsheet As Worksheet
Set datasheet = Sheet1
set reportsheet = Sheet2
Of course this doesnt work anymore since I deleted Sheet2 and excel remembers your past mistakes. I tried to circumvent this by doing following:
Set datasheet = Sheet1
'Create reportsheet if it doesnt exist
Dim ws As Worksheet
CreateSheetIf = False
Set ws = Nothing
On Error Resume Next
Set ws = ActiveWorkbook.Worksheets("reportdata")
On Error GoTo 0
If ws Is Nothing Then
CreateSheetIf = True
Worksheets.Add.Name = "reportdata"
End If
Set reportsheet = ws
Unfortunately, here I run into an error in my later code which tries to empty the reportsheet:
reportsheet.Range("A1:H200").ClearContents
What I would like to have is to create a new sheet in addition to sheet1 if there is none. This sheet should be located after the Sheet1 in the sheet listing. My further code would utilize this as the reportsheet (I move data from Sheet1 to Sheet2). Someone has any tips on what I am doing wrong and how to do it better?
You do not need to rename the sheet, or have it called Sheet1 and Sheet2. You could access it dynamically relative to their index. For example:
Set datasheet = Worksheets(1) ' The first sheet in the workbook
set reportsheet = Worksheets(2) ' The second sheet in the workbook
I see lack of focus there, you first try to refer to worksheets by Object name (Sheet1, Sheet2) and then by Tab name ("reportdata").
Set ws = ActiveWorkbook.Worksheets("reportdata") with error supression is a good way to handle it, although you try to do the following after:
Set reportsheet = ws
The problem is that if you go through code, you will notice that at this stage Object ws is Nothing if there was no "reportdata" worksheet prior to running this code.
Use:
Set reportsheet = ActiveWorkbook.Worksheets("reportdata")
You can use the worksheet index number instead of the codename.
Option Explicit
Sub repBuild()
Dim datasheet As Worksheet
Dim reportsheet As Worksheet
Set datasheet = Sheet1
On Error GoTo createSecondWs
Set reportsheet = Worksheets(2)
On Error GoTo 0
'build report here with reportsheet
Exit Sub
createSecondWs:
With Worksheets.Add(after:=Worksheets(Worksheets.Count))
.Name = "Report Sheet"
'perform other basic report template operations here before returning
End With
Resume
End Sub
This uses error control to create a second worksheet if only one exists.

Subscript out of range Midcoded error

Usually with a subscript out of range error, something is misspelled. This time I can guarantee that it is not misspelled. I am declaring workbook and sheets names as variables to be used later for simple copy paste stuff. But when I define one of my sheets as Set main=wb.Sheets("Primary") I get the error, subscript out of range. I did't believe it, so I copied what I wrote and pasted that as the Sheet name. Same error. Therefore, their must be an issue with how I set up my Workbook/Worksheets. Any help much appreciated.
Sub copyPaste()
Dim wb As Workbook
Dim main As Sheets
Dim hypo As Sheets
Set wb = ThisWorkbook
Set main = wb.Sheets("Primary")
Set hypo = wb.Sheets("Hypo")
Application.CutCopyMode = False
wb.main.Range("D22:D46").Value = wb.main.Range("D22:D46").Value
End Sub
You want Worksheet (singular) not Sheets (plural) (Sheets is a collection of worksheets)
Dim main As WorkSheet
Dim hypo As WorkSheet
and here you dont use the workbook object because it's already defined as part of the worksheet reference. Change it to this
main.Range("D22:D46").Value = main.Range("D22:D46").Value

VBA: Referencing a Worksheet in the Active Workbook

While this seems very basic, I am continually getting an error message while trying to select a cell in a certain sheet on my workbook in my Macro. Does any one know why this will not work? I'm getting error message Run Time Error '1004'.
The sheets name is "Sheet1"and my code is below:
Application.ActiveWorkbook.Worksheets("Sheet1").Range("N2").Select
It's bad practice to use ActiveWorkbook when you don't need to. It's always better to set your workbooks and worksheets to actual variables that you can call on. I think your code is activating another workbook then trying to select a range in a worksheet it can't find.
Sub TryThis()
Dim wbk As Workbook
Dim ws As Worksheet
Set wbk = Workbooks("myWorkbook.xlsm")
Set ws = wbk.Worksheets("Sheet1")
'Now when we say "ws." it is actually "Workbooks("myWorkbook.xlsm").Worksheets("Sheet1")."
'This is okay to start with but it's better to work with the cells directly
ws.Select
Range("N2").Select
Selection = "myText"
'This is much faster and you won't have to worry about what is currently selected
ws.Range("N2") = "myText"
End Sub

How to generate sheet from template

In VBA, i would like create a new sheet from a template after my first sheet.
Example:
In MyFirstSheet i have cell B16="House" and a button "NewSheetFromTemplate". When user click on the button a new sheet generated after my MyFirstSheet and contains same information than TEMPLATE sheet with title House.
My VBA code:
Sub NewSheetFromTemplate()
Dim sht As Worksheet
Set sht = Sheets("TEMPLATE").Copy After:=sheets("MyFirstSheet")
sht.Name = Range("B16").Value
End Sub
Excel say me "Syntax error" but why ?
I don't think is it really necessary to create Worksheet object just to rename it. Try simply like this:
Sub NewSheetFromTemplate()
Sheets("TEMPLATE").Copy After:=Sheets("MyFirstSheet")
ActiveSheet.Name = Sheets("MyFirstSheet").Range("B16").Value
End Sub
The following line of code does not return an object, one is created but this is not returned to VBA:
Sheets("TEMPLATE").Copy After:=sheets("MyFirstSheet")
This means that you cannot set this line of code to an object. Instead, try something like either of the following two options:
Using Index
Because you've copied the new worksheet after Sheets("MyFirstSheet") you can use the worksheet index of Sheets("MyFirstSheet") and then add 1 to get the sheet you've just created.
Sub NewSheetFromTemplate()
Dim sht As Worksheet
Sheets("TEMPLATE").Copy After:=sheets("MyFirstSheet")
Set sht = Sheets(Sheets("MyFirstSheet").Index+1)
sht.Name = Range("B16").Value
End Sub
Using "Name (2)"
Alternatively, the default name for a copied sheet is the original name with " (2)" tagged onto the end. This is still a useful way of identifying the new worksheet however it could become an issue if the original worksheet has a particularly long name.
Sub NewSheetFromTemplate()
Dim sht As Worksheet
Sheets("TEMPLATE").Copy After:=sheets("MyFirstSheet")
Set sht = Sheets("TEMPLATE (2)")
sht.Name = Range("B16").Value
End Sub
You can't create an instance of a Worksheet via Copy method. Since you know where are you placing the new sheet, you are able to find it after copied, and rename it. You are very close:
Sheets("TEMPLATE").Copy After:=Sheets("MyFirstSheet")
Sheets(Sheets("MyFirstSheet").Index + 1).Name = Sheets("TEMPLATE").Range("B16").Value
Make sure that you have a value in B16 range.
Hope this helps,
Cheers.

Copy an entire worksheet to a new worksheet in Excel 2010

I have found similar questions that deal with copying an entire worksheet in one workbook and pasting it to another workbook, but I am interested in simply copying an entire worksheet and pasting it to a new worksheet -- in the same workbook.
I'm in the process of converting a 2003 .xls file to 2010 .xlsm and the old method used for copying and pasting between worksheets doesn't paste with the correct row heights. My initial workaround was to loop through each row and grab the row heights from the worksheet I am copying from, then loop through and insert those values for the row heights in the worksheet I am pasting to, but the problem with this approach is that the sheet contains buttons which generate new rows which changes the row numbering and the format of the sheet is such that all rows cannot just be one width.
What I would really like to be able to do is just simply copy the entire worksheet and paste it. Here is the code from the 2003 version:
ThisWorkbook.Worksheets("Master").Cells.Copy
newWorksheet.Paste
I'm surprised that converting to .xlsm is causing this to break now. Any suggestions or ideas would be great.
It is simpler just to run an exact copy like below to put the copy in as the last sheet
Sub Test()
Dim ws1 As Worksheet
Set ws1 = ThisWorkbook.Worksheets("Master")
ws1.Copy ThisWorkbook.Sheets(Sheets.Count)
End Sub
ThisWorkbook.Worksheets("Master").Sheet1.Cells.Copy _
Destination:=newWorksheet.Cells
The above will copy the cells. If you really want to duplicate the entire sheet, then I'd go with #brettdj's answer.
' Assume that the code name the worksheet is Sheet1
' Copy the sheet using code name and put in the end.
' Note: Using the code name lets the user rename the worksheet without breaking the VBA code
Sheet1.Copy After:=Sheets(Sheets.Count)
' Rename the copied sheet keeping the same name and appending a string " copied"
ActiveSheet.Name = Sheet1.Name & " copied"
I really liked #brettdj's code, but then I found that when I added additional code to edit the copy, it overwrote my original sheet instead. I've tweaked his answer so that further code pointed at ws1 will affect the new sheet rather than the original.
Sub Test()
Dim ws1 as Worksheet
ThisWorkbook.Worksheets("Master").Copy
Set ws1 = ThisWorkbook.Worksheets("Master (2)")
End Sub
'Make the excel file that runs the software the active workbook
ThisWorkbook.Activate
'The first sheet used as a temporary place to hold the data
ThisWorkbook.Worksheets(1).Cells.Copy
'Create a new Excel workbook
Dim NewCaseFile As Workbook
Dim strFileName As String
Set NewCaseFile = Workbooks.Add
With NewCaseFile
Sheets(1).Select
Cells(1, 1).Select
End With
ActiveSheet.Paste
If anyone has, like I do, an Estimating workbook with a default number of visible pricing sheets, a Summary and a larger number of hidden and 'protected' worksheets full of sensitive data but may need to create additional visible worksheets to arrive at a proper price, I have variant of the above responses that creates the said visible worksheets based on a protected hidden "Master". I have used the code provided by #/jean-fran%c3%a7ois-corbett and #thanos-a in combination with simple VBA as shown below.
Sub sbInsertWorksheetAfter()
'This adds a new visible worksheet after the last visible worksheet
ThisWorkbook.Sheets.Add After:=Worksheets(Worksheets.Count)
'This copies the content of the HIDDEN "Master" worksheet to the new VISIBLE ActiveSheet just created
ThisWorkbook.Sheets("Master").Cells.Copy _
Destination:=ActiveSheet.Cells
'This gives the the new ActiveSheet a default name
With ActiveSheet
.Name = Sheet12.Name & " copied"
End With
'This changes the name of the ActiveSheet to the user's preference
Dim sheetname As String
With ActiveSheet
sheetname = InputBox("Enter name of this Worksheet")
.Name = sheetname
End With
End Sub