VBA create new Worksheet if not exists - vba

I am currently working on a VBA macro, that takes data from a Worksheet and copies it to another.
If the destination Worksheet does not exist it should create it and than write the data from my array.
Problem:
I have a function to test if the worksheet already exists.
If it is the case my macro will successfully write the data i want. But if the worksheet doesnt exist VBA is displaying the error you can see below.
In the list Workbook.Worksheets is no Sheet named like this but I get that error anyway.
Here is my relevant code:
(If something is missing for understanding the problem I can fill in the missing part in too)
Function sheetExists(sheetToFind As String) As Boolean
Dim Sheet As Worksheet
For Each Sheet In Worksheets
If sheetToFind = Sheet.Name Then
sheetExists = True
Exit Function
End If
Next Sheet
sheetExists = False
End Function
In my main Sub I used this code:
If sheetExists("SheetName") = False Then
Dim newSheet As Worksheet
With ThisWorkbook
.Sheets.Add(After:=Worksheets(Worksheets.Count)).Name = "SheetName"
End With
End If
The exact error:
1004 Cannot rename a sheet to the same name as another sheet, a reference object library, or a workbook referenced by Visual Basic
First it was executing successfully but after I deleted the sheet manually the error occurred.
Thanks for any help :)

Specify in which workbook to look at:
For Each Sheet In ThisWorkbook.Sheets
also not that it has to be Sheets and not Worksheets, because Worksheets only contains worksheets but Sheets also contains charts, etc. So we have to check these names too!
(Sheet then has to be Dim Sheet As Object)
You can make your function more flexible:
Function sheetExists(sheetToFind As String, Optional InWorkbook As Workbook) As Boolean
If InWorkbook Is Nothing Then Set InWorkbook = ThisWorkbook
Dim Sheet As Object
For Each Sheet In InWorkbook.Sheets
If sheetToFind = Sheet.Name Then
sheetExists = True
Exit Function
End If
Next Sheet
sheetExists = False
End Function
so you can call it:
sheetExists("SheetName") to use ThisWorkbook by default, or
sheetExists("SheetName", Workbooks("MyWorkbook")) to specify a specific workbook.
Alternatively you can use
Function sheetExists(sheetToFind As String, Optional InWorkbook As Workbook) As Boolean
If InWorkbook Is Nothing Then Set InWorkbook = ThisWorkbook
On Error Resume Next
sheetExists = Not InWorkbook.Sheets(sheetToFind) Is Nothing
End Function
which can be a bit faster if there are many sheets in a workbook.

Related

I am unable to get the correct worksheet name when looping through a workbook

I am trying to collect data from multiple workbooks by checking the worksheet names.
However when i run my code to check the worksheetname(which is Raw Data), i am getting a false result. The code is returning only Sheet1 and Sheet2.
Below is the code:
Function WorksheetRAWExists(wsName As String) As Boolean
Dim ws As Worksheet
Dim ret As Boolean
ret = False
wsName = UCase(wsName)
For Each ws In ThisWorkbook.Sheets
If UCase(ws.Name) = "RAW DATA" Then
ret = True
Exit For
End If
Next
WorksheetRAWExists = ret
End Function
This happens because you loop through "ThisWorkbook" in your for-each, which always checks the worksheet collection in the workbook you're running the VBA code from.
If you're looking to loop through all sheets in all open workbooks then you could do something like so:
Sub test()
Dim wbk As Workbook, ws As Worksheet
For Each wbk In Workbooks
For Each ws In wbk.Worksheets
MsgBox ws.Name
Next ws
Next wbk
End Sub
Edit:
You could also pass the workbook name or index (or the workbook reference itself) to your function and check that specific reference in the workbook collection, in case looping through all open workbooks isn't what you want.

How to copy the sheet name to a column on the same sheet?

I am using this code:
Function wrksht() as Variant
wrksht = Application.Caller.Parent.Name
End function
I am continuously being thrown
run time error '424' object not found
I have a workbook with several sheets, each having a date on it.
I want to populate the first column on every sheet with its sheet name.
Function wrksht() as String
wrksht = ActiveSheet.Name
End function
UPDATE
Function DoIt()
Dim sh As Worksheet
For Each sh In ActiveWorkbook.Sheets
sh.Range("A1") = sh.Name
Next
End Function
The above will work, but I have an easier solution:
=MID(CELL("filename",A1),FIND("]",CELL("filename",A1))+1,255)
Paste this value (it is a formula, not VBA code) into the cell you wish to populate with the sheet name, and it will magically appear.
Try this
Sub my_macro
On error resume next
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Sheets
ws.Range("A1") = ws.Name
Next
End sub

Using Worksheet.Change event to add a new worksheet

I have a range of cells (specifically D6:D34) where all the values in the cells have a corresponding sheet. However, since I've been just manually adding worksheets when I add a new value (or change a cell value), I'm thinking about using Private Sub Worksheet_Change(ByVal Target as Range) to allow the automatic creation of a worksheet when the cells change. This is what I've tried to use, but now I'm getting an error that the "sheet name already exists" as it looks down the whole column. I've tried using error handling to skip over ones that exist, but it ends up moving to the next one to check but leaving "Sheet1" and "Sheet2", etc. Any suggestions on how to set this up?
Private Sub Worksheet_Change(ByVal Target As Range)
Dim hlValue As Range
For Each hlValue In Sheets(1).Range("D6:D34")
ActiveWorkbook.Sheets.Add after:=Worksheets(Worksheets.Count)
ActiveSheet.Name = hlValue
Next
End Sub
I should also say that if one of the cell value is deleted, the worksheet should be deleted as well. Some sort of If CellValue <> Exist, Delete? I couldn't find anything to use to check if it exists besides fancy functions. Should I use one of these?
EDIT: Okay, I've got this now. This should suffice.
Private Sub Worksheet_Change(ByVal Target As Range)
Application.DisplayStatusBar = True
Application.ScreenUpdating = False 'Run faster
Application.DisplayAlerts = False 'Just in case
Dim shtName As Variant
For Each shtName In Sheets(1).Range("D6:D34")
If WorksheetExists((shtName)) Then
'do nothing
Else
ActiveWorkbook.Sheets.Add after:=Worksheets(Worksheets.Count)
ActiveSheet.Name = shtName
Application.StatusBar = "Creating new sheet for " & shtName 'Just in case it's running slowly
Sheets("Admin").Select
End If
Next
Application.StatusBar = "READY"
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Function WorksheetExists(sName As String) As Boolean
WorksheetExists = Evaluate("ISREF('" & sName & "'!A1)")
End Function
I couldn't find anything to use to check if it exists besides fancy functions. Should I use one of these?
Yes, you should! Worksheets are part of a Collection object and there is no built-in Exists (or similar) method that you can query. Such a function is not fancy :) and it would be a good introduction to using functions and/or calling other subroutines, if you're not familiar with that already.
At it's simplest:
Function SheetExists(sName As String) As Boolean
Dim w as Worksheet
On Error Resume Next
Set w = Worksheets(sName)
SheetExists = Not w Is Nothing
End Function
How this works:
If SheetExists("sheet1") Then
'Do something
Else
'Sheet doesn't exist, so do something else
End If
You pass a string value to the function as sName. THe function then returns True or False whether this sheet exists.
First, the function SheetExists attempts to set a Worksheet variable to the specified worksheet, by name. This will predictably fail if the worksheet name doesn't exist, so we use this knowledge along with the Resume Next statement. In the case of an error, w will not be assigned a worksheet and will remain a Nothing, and then we use a boolean expression (Not w Is Nothing) as the function's return value. If the sheet does exist, w will not be nothing, so the function will return True, and if the sheet doesn't exist, w will be Nothing, so the function will return False.
The function above only uses the ActiveWorkbook, so a more robust version of this would also allow you to specify a parent workbook.
Function SheetExists(sName As String, Optional wb as Workbook = Nothing) As Boolean
'This function checks whether worksheet 'sName' exists in
' workbook object 'wb'. If no parameter is passed for 'wb' then
' assume to use the ActiveWorkbook
Dim w as Worksheet
If wb Is Nothing Then Set wb = ActiveWorkbook
On Error Resume Next
Set w = wb.Worksheets(sName)
SheetExists = Not w Is Nothing
End Function
NB: There are relatively few cases where On Error Resume Next is not frowned upon, but using this in a very small and specific Function, with a well-defined purpose and expectation is OK.
Alternatively, brute force iteration over the collection's Items may also be used to query collections for existence, and this does not rely on On Error Resume Next:
Function SheetExists2(sName as String) As Boolean
Dim ws as Worksheet, ret as Boolean
For Each ws In ActiveWorkbook.Worksheets
If ws.Name = sName Then
ret = True
Exit For
End If
Next
SheetExists2 = ret
End Function

Using VBA to copy a spreadsheet from a secondary workbook into the primary one

I need to take a spreadsheet and compare it with a spreadsheet from another workbook. I know that I can do this using VBA, but I will need to copy a spreadsheet from another workbook so that both spreadsheets will reside within the same workbook and be accessible for comparison. How do I copy a spreadsheet from one workbook into another using VBA?
You don't need to copy the worksheets over to compare them. Simply open both WorkBooks and and set reference to there WorkSheets.
Sub CompareWorkBooks()
Dim wbPending As Workbook
Dim wsPending As Worksheet
Set wbPending = Workbooks("Items Pending")
Set wsPending = wsPending.Worksheet("Items")
Dim wbRecieved As Workbook
Dim wsRecieved As Worksheet
Set wbRecieved = Workbooks("Items Recieved")
Set wsRecieved = Worksheet("Items")
End Sub
If you provide names for Workbooks & WorkSheets and provide column information, we can give you better answers in a shorter period of time. Don't be afraid to post your code either.
If you want a user to select the target workbook and worksheet:
Create a userform
Declare targetWorkbook and tartgetWorksheet at the top of the code module
Add a command button and a combo box
When the button is clicked a file dialog is opened
A reference is now set to the open file
The names of all the worksheets are added to the combo
Changing the combo box value will set the refernce to tartgetWorksheet
Option Explicit
Public targetWorkbook As Workbook
Public tartgetWorksheet As Worksheet
Private Sub CommandButton1_Click()
Dim targetWorkbook As Workbook
Dim ws As Worksheet
Set targetWorkbook = getTargetWorkbook
If targetWorkbook = Nothing Then
MsgBox "Sowmthing went wrong", vbCritical, "Try Again"
Else
For Each ws In targetWorkbook.Worksheets
ComboBox1.AddItem ws.Name
Next
End If
End Function
Function getTargetWorkbook() As Workbook
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
.Show
On Error Resume Next
Set getTargetWorkbook = Application.Workbooks.Open(.SelectedItems(1))
On Error GoTo 0
End With
End Function
Private Sub ComboBox1_Change()
Set tartgetWorksheet = targetWorkbook.Worksheets(ComboBox1.Value)
End Sub

In VBA check which excel sheet is active (currently shown)

I'm looking for a method of checking if an excel sheet is currently active (currently shown).
I'm interested in a synchronous method and not in an event.
You could use set sh = ActiveSheet, or strShName = ActiveSheet.Name.
To test if sheet Xyz is active: If ActiveSheet.Name = "xyz" Then
You can also use If ActiveSheet.CodeName = "Sheet1" Then (VBE name)
Test for matching worksheet and workbook names.
Function IsActiveSheet(ByVal targetSheet As Worksheet) As Boolean
IsActiveSheet = targetSheet.Name = ActiveSheet.Name And _
targetSheet.Parent.Name = ActiveWorkbook.Name
End Function
It's a function. Place it in a module, and then call it from another procedure like this:
Sub Test()
Dim mySheetVar As Worksheet
Set mySheetVar = ActiveWorkbook.Worksheets("Sheet1")
' Here's the function call which returns TRUE or FALSE.
MsgBox IsActiveSheet(mySheetVar)
End Sub
If Sheet1 Is ActiveSheet Then
Call
ElseIf Sheet2 Is ActiveSheet Then