I have a main worksheet (Install_Input) where sheet number, test section, and material are manually entered by user.
(Below: illustration of Install_Input ws: Range A1:C8)
Sheet# | TestSection | Material
.....1.....|..........A..........|.STEEL.|
.....2.....|..........B..........|.PLASTIC.|
.....3.....|..........C..........|.STEEL.|
.....5.....|..........G..........|.STEEL.|
.....2.....|..........F..........|.PLASTIC.|
.....2.....|..........A..........|.STEEL.|
.....5.....|..........D..........|.PLASTIC.|
I want to generate sheets within the current workbook that correspond to sheet numbers entered in Install_Input. The code I made will generate a new sheet for each value in MyRange, however, I would like for my code to skip over generating sheets that already exist. I tried using the "On Error Resume Next" and "On Error GoTo 0" commands to solve this problem, but they just generated unnamed sheets to compensate for those that already exist.
Sub Consolidate_Sheets()
Dim MyCell As Range
Dim MyRange As Range
Dim ws As Worksheet
Set MyRange = Sheets("Install_Input").Range("A2")
Set MyRange = Range(MyRange, MyRange.End(xlDown))
For Each MyCell In MyRange
If Sheets(Sheets.Count).Name <> MyCell.Value Then
'On Error Resume Next
Sheets.Add After:=Sheets(Sheets.Count)
Sheets(Sheets.Count).Name = MyCell.Value
'On Error GoTo 0
End If
Next MyCell
End Sub
You can use the following two functions:
Function getSheetWithDefault(name As String, Optional wb As Excel.Workbook) As Excel.Worksheet
If wb Is Nothing Then
Set wb = ThisWorkbook
End If
If Not sheetExists(name, wb) Then
wb.Worksheets.Add(After:=wb.Worksheets(wb.Worksheets.Count)).name = name
End If
Set getSheetWithDefault = wb.Sheets(name)
End Function
Function sheetExists(name As String, Optional wb As Excel.Workbook) As Boolean
Dim sheet As Excel.Worksheet
If wb Is Nothing Then
Set wb = ThisWorkbook
End If
sheetExists = False
For Each sheet In wb.Worksheets
If sheet.name = name Then
sheetExists = True
Exit Function
End If
Next sheet
End Function
To use it in your code:
Sub Consolidate_Sheets()
Dim MyCell As Range
Dim MyRange As Range
Dim ws As Worksheet
Set MyRange = Sheets("Install_Input").Range("A2")
Set MyRange = Range(MyRange, MyRange.End(xlDown))
For Each MyCell In MyRange
If Sheets(Sheets.Count).Name <> MyCell.Value Then
'On Error Resume Next
set ws = getSheetWithDefault(MyCell.Value)
'On Error GoTo 0
End If
Next MyCell
End Sub
You could implement a CheckSheet function like the one described in this SO answer that loops through all existing sheets and compares the name of each sheet with the passed-in value.
Related
I'm trying to create a new sheet labeled with a different identifier from a range and also have two cells from other ranges included on each update. I can get the new sheets to create with a different label from a range, and have the first cell in the second range (xRg2) added to each subsequent sheet, but haven't been successful at iterating through the second range. I know I need another loop somewhere but my last nest created way too many sheet. See example below
Sub Add()
Dim xRg As Excel.Range
Dim xRg2 As Excel.Range
Dim wSh As Excel.Worksheet
Dim wBk As Excel.Workbook
Dim wSh2 As Excel.Worksheet
Dim wSh3 As Excel.Worksheet
Set wSh = ActiveSheet
Set wBk = ActiveWorkbook
Set wSh2 = ThisWorkbook.Sheets("List")
Set wSh3 = ThisWorkbook.Sheets("Template")
Set xRg2 = wSh2.Range("G66:G88")
Application.ScreenUpdating = False
For Each xRg In wSh2.Range("B66:B88")
With wBk
wSh3.Copy after:=.Sheets(.Sheets.Count)
On Error Resume Next
wSh.Name = xRg.Value
wSh.Cells(33,7) = xRg2.Value
If Err.Number = 1004 Then
Debug.Print xRg.Value & "already used as a sheet name"
End If
On Error GoTo 0
End With
Next xRg
Application.ScreenUpdating = True End Sub
So, to summarize, the goal here is to input the ranges into the code each time and have each new sheet include the first values from each range, then the second sheet the second values from each range, and so on until the xRg is at the end of it's list. I know there's only two ranges down here but the total will be 3. Also apologies on the poor variable discipline...
Thanks!
Try something like this (sorry do not like all those x... variable names)
Sub Add()
Dim c As Range
Dim wb As Workbook, ws As Worksheet, wsList As Worksheet
Set wb = ActiveWorkbook
Set wsList = wb.Worksheets("List")
Application.ScreenUpdating = False
For Each c In wsList.Range("B66:B88").Cells
ThisWorkbook.Sheets("Template").Copy after:=wb.Sheets(wb.Sheets.Count)
Set ws = wb.Sheets(wb.Sheets.Count) '<< get the just-created sheet copy
On Error Resume Next
ws.Name = c.Value
ws.Cells(33, 7) = c.EntireRow.Columns("G").Value
If Err.Number = 1004 Then
Debug.Print "'" & c.Value & "' already used as a sheet name"
End If
On Error GoTo 0
Next c
Application.ScreenUpdating = True
End Sub
In this workbook, I have 2 worksheets- (CAM) & (DIST)
On (CAM) is a table titled "Distributor". If I enter a name into this table, I want the (DIST) tab to duplicate and be renamed to what I just entered in the "Distributor" table on sheet 1.
This is code I tried using but..... im not good at this and don't understand very well.
Sub AddSheets()
Dim xRg As Excel.Range
Dim wSh As Excel.Worksheet
Dim wBk As Excel.Workbook
Set wSh = ActiveSheet
Set wBk = ActiveWorkbook
Application.ScreenUpdating = False
For Each xRg In wSh.Range("A1:A7")
With wBk
.Sheets.Add after:=.Sheets(.Sheets.Count)
On Error Resume Next
ActiveSheet.Name = xRg.Value
If Err.Number = 1004 Then
Debug.Print xRg.Value & " already used as a sheet name"
End If
On Error GoTo 0
End With
Next xRg
Application.ScreenUpdating = True
End Sub
Your program may work as follows:
1. For each entry in cam, check if a coresponding worksheet exists
2. if not, then create the worksheet by duplicating the dist worksheet:
Dim wBk As Workbook
Dim wSh as Worksheet, wNw as Worksheet
Dim xRg as Range
Set wBk = ActiveWorkbook
Set wSh = wBk.Workhseets("CAM")
Set xRg = wSh.Range("B2") ' Assuming your table "CAM" starts in cell B2
while not xRg.Value = ""
on error resume next
set wSh = wBk.Worksheets(xRg.Value) ' --- Try accessing worksheet
on error goto 0 ' --- Remove error handler
if wSh is nothing then ' --- no worksheet
set sSh = wBk.Worksheets("Dist") ' --- Source worksheet
set sNw = wBk.Worksheets.Add() ' --- New worksheet as target
sSh.UsedRange.Copy ' --- Copy all from source
sNw.Range("A1").PasteSpecial xlPasteAll
end if
wend
Good luck!
I have a template sheet that I have set up named "Template".
I have a range of cells on another worksheet called "Formulation" that I would like it to look through the range "G7:W7" and create a copy of the "Template" and rename it accordingly.
I have adapted a piece of code I have found but I keep encountering a run time error 13 - type mismatch.
Here is the code:
`Sub CopyInfoSheetandInsert()
'
' CopyInfoSheetandInsert Macro
'
Dim rcell As Range
Dim Background As Worksheet
Set Background = Sheets("Formulation")
For Each rcell In Range("D7:W7")
If rcell.Value <> "" Then
Sheets("Template").Copy Before:=Sheets("COSHH")
Sheets("Template (2)").Name = rcell.Value
End If
Next rcell
End Sub
Any advice would be greatly appreciated!
UPDATE
By moving the macro button to the formulation page the copy function now works however, on the following line of code I now get a subscript out of range error?
Sheets("Template(2)").Name = rcell.Value
Kind Regards,
Aidan
You need something like:
Sub CopyInfoSheetandInsert()
Dim rcell As Range
Dim Background As Worksheet
Set Background = Sheets("Formulation")
For Each rcell In Range("D7:W7")
If rcell.Value <> "" And SheetExists(rcell.Value) = False Then
Sheets("Template").Copy Before:=Sheets("COSHH")
Sheets(Sheets("COSHH").Index - 1).Name = rcell.Value
End If
Next rcell
End Sub
Function SheetExists(SheetName) As Boolean
Dim sht As Worksheet
'Assume Failure
SheetExists = False
For Each sht In ActiveWorkbook.Sheets
If sht.Name = SheetName Then
'Success
SheetExists = True
Exit Function
End If
Next sht
End Function
HI I have created a VBA that takes info from a ALL data sheet and plots it in worksheets.
The worksheets get automatically generated which is great but the issue is that VBA is only supposed to create Unique worksheets - however this is not the case.
Example: if in my ALL data sheet I have IKEA 3 times then the first time the vba encounters IKEA then it should create a worksheet while it should ignore any repeats.
Actual
IKEA; Sheet 2 ; Sheet 3
Wanted
IKEA
VBA Code
Sub CreateSheetsFromAList()
Dim iReply As Integer
Dim MyCell As Range, MyRange As Range
On Error Resume Next
Range("B1").End(xlUp).AdvancedFilter _
Action:=xlFilterCopy, CopyToRange:=rListPaste.Cells(1, 1), Unique:=True
Set MyRange = Sheets("ALL").Range("B1")
Set MyRange = Range(MyRange, MyRange.End(xlDown))
For Each MyCell In MyRange
Sheets.Add After:=Sheets(Sheets.Count) 'creates a new worksheet
Sheets(Sheets.Count).Name = MyCell.Value ' renames the new worksheet
Next MyCell
End Sub
Try this code (it creates new sheet only if there is no sheets with name MyCell.Value):
Sub CreateSheetsFromAList()
Dim iReply As Integer
Dim MyCell As Range, MyRange As Range
Dim sh as Worksheet
On Error Resume Next
Range("B1").End(xlUp).AdvancedFilter _
Action:=xlFilterCopy, CopyToRange:=rListPaste.Cells(1, 1), Unique:=True
Set MyRange = Sheets("ALL").Range("B1")
Set MyRange = Range(MyRange, MyRange.End(xlDown))
For Each MyCell In MyRange
Set sh = Nothing
Set sh=Sheets(MyCell.Value)
If sh is Nothing Then
Sheets.Add After:=Sheets(Sheets.Count) 'creates a new worksheet
Sheets(Sheets.Count).Name = MyCell.Value ' renames the new worksheet
End If
Next MyCell
End Sub
I have an existing worksheet "StudentSheet1" which I need to add as many times as a user needs.
For eg, if a user enters 3 in cell "A1", saves it and closes the workbook.
I want to have three sheets: "StudentSheet1" , "StudentSheet2" and "StudentSheet3" when the workbook is opened next time.
So I will have the Code in "Workbook_Open" event. I know how to insert new sheets, but cant insert this particular sheet "StudentSheet1" three times
Here is my code:
Private Sub Workbook_Open()
Application.ScreenUpdating = False
Dim ws As Worksheet
Set ws = ActiveWorkbook.Sheets.Add(Type:=xlWorksheet, After:=Worksheets(1))
Application.ScreenUpdating = True
End Sub
EDIT
Sorry I misread the question, try this:
Private Sub Workbook_Open()
Dim iLoop As Integer
Dim wbTemp As Workbook
If Not Sheet1.Range("A1").value > 0 Then Exit Sub
Application.ScreenUpdating = False
Set wbTemp = Workbooks.Open(Filename:="//Ndrive/Student/Student.xlsm")
wbTemp.Sheets("StudentSheet1").Copy After:=ThisWorkbook.Sheets(Sheets.Count)
wbTemp.Close
Set wbTemp = Nothing
With Sheet1.Range("A1")
For iLoop = 2 To .Value
Sheets("StudentSheet1").Copy After:=ThisWorkbook.Sheets(Sheets.Count)
ActiveSheet.Name = "StudentSheet" & iLoop
Next iLoop
.Value = 0
End With
Application.ScreenUpdating = True
End Sub
Why are you wanting to add sheets on the workbook open? If the user disables macros then no sheets will be added. As Tony mentioned, why not add the sheets when called by the user?
EDIT
As per #Sidd's comments, if you need to check if the sheet exists first use this function:
Function SheetExists(sName As String) As Boolean
On Error Resume Next
SheetExists = (Sheets(sName).Name = sName)
End Function
user793468, I would recommend a different approach. :)
wbTemp.Sheets("StudentSheet1").Copy After:=ThisWorkbook.Sheets(Sheets.Count)
is not reliable. Please see this link.
EDIT: The above code will fail if the workbook has defined names. Otherwise it is absolutely reliable. Thanks to Reafidy for catching that.
I just noticed OP's comment about the shared drive. Adding amended code to incorporate OP's request.
Tried and Tested
Option Explicit
Const FilePath As String = "//Ndrive/Student/Student.xlsm"
Private Sub Workbook_Open()
Dim wb1 As Workbook, wb2 As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet
Dim TempName As String, NewName As String
Dim ShtNo As Long, i As Long
On Error GoTo Whoa
Application.ScreenUpdating = False
Set wb1 = ActiveWorkbook
Set ws1 = wb1.Sheets("Sheet1")
ShtNo = ws1.Range("A1")
If Not ShtNo > 0 Then Exit Sub
Set wb2 = Workbooks.Open(FilePath)
Set ws2 = wb2.Sheets("StudentSheet1")
For i = 1 To ShtNo
TempName = ActiveSheet.Name
NewName = "StudentSheet" & i
If Not SheetExists(NewName) Then
ws2.Copy After:=wb1.Sheets(Sheets.Count)
ActiveSheet.Name = NewName
End If
Next i
'~~> I leave this at your discretion.
ws1.Range("A1").ClearContents
LetsContinue:
Application.ScreenUpdating = True
On Error Resume Next
wb2.Close savechanges:=False
Set ws1 = Nothing
Set ws2 = Nothing
Set wb2 = Nothing
Set wb1 = Nothing
On Error GoTo 0
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