I made the macro code so that it checks cell "w6" in all worksheets when the excel file opens. When "w6" is empty, it should hide graph "FG" and only show graph "F".
When "w6" is not empty, it should hide graph "F" and only show graph "FG". I set the names of each graph as "F" and "FG". But there is an error message in the
wsht.Shapes.Range(Array("FG")).Visible = msoFalse line in the HideFG macro that "the item with the specified name wasn't found." I am sure that the graph name is "FG", but why is this happening? Is there an excel genius who can solve this?
Private Sub Workbook_Open()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Sheets
With ws
If .Range("W6").Value = 0 Then
HideFG ws
Else
HideF ws
End If
End With
Next
End Sub
Sub HideF(wsht As Worksheet)
'
' HideF Macro
'
'
For i = 1 To wsht.Shapes.Count
wsht.Shapes(i).Visible = msoTrue
Next i
wsht.Shapes.Range(Array("F")).Visible = msoFalse
Application.CommandBars("Selection").Visible = False
End Sub
Sub HideFG(wsht As Worksheet)
'
' HideFG Macro
'
'
For i = 1 To wsht.Shapes.Count
wsht.Shapes(i).Visible = msoTrue
Next i
wsht.Shapes.Range(Array("FG")).Visible = msoFalse
Application.CommandBars("Selection").Visible = False
End Sub
Instead of calling another macro, you could just simply try the following:
If what you refer to are actually Shapes:
Private Sub Workbook_Open()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Sheets
ws.Shapes.Range(Array("F", "FG")).Visible = False
If ws.[W6] = 0 Then
ws.Shapes("F").Visible = True
Else
ws.Shapes("FG").Visible = True
End If
Next ws
End Sub
Or when they actually are ChartObjects then:
Private Sub Workbook_Open()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Sheets
If ws.[W6] = 0 Then
ws.ChartObjects("F").Visible = True
ws.ChartObjects("FG").Visible = False
Else
ws.ChartObjects("F").Visible = False
ws.ChartObjects("FG").Visible = True
End If
Next ws
End Sub
As per this question of yours, I feel you might not want to loop all the sheets.
In that case, change:
For Each ws In ThisWorkbook.Sheets
Into:
For Each ws In Sheets(Array("sheet1", "sheet2", "sheet3"))
Let me know if it works for you :)
Related
I have an issue with below code.
I want to delete all visible sheets but a certain sheet, when a user closes the workbook.
This is the code:
Private Sub workbook_BeforeClose(cancel As Boolean)
Dim ws As Worksheet
For Each ws In Workbook
If ws.Visible = xlSheetVisible Then
If ws.Name <> "Choose BU" Then ws.Delete
End If
Next ws
End Sub
It says "Object required", however I thought the worksheet per default is an object in VBA?
You could try:
Option Explicit
Sub test()
Dim ws As Worksheet
Application.DisplayAlerts = False
For Each ws In ThisWorkbook.Worksheets
With ws
If .Visible = True And .Name <> "Choose BU" Then
.Delete
End If
End With
Next ws
Application.DisplayAlerts = True
End Sub
I am trying to reference sheet 1, sheet 2 sheet 3 for my macro. At the moment, I referenced sheet 1 but I don't know how to reference multiple sheets. I hope that in all sheets, cell w6 is checked. Many thanks in advance! :)
Hide F macro is to hide a graph names "F" and show graph "FG" when cell w6 is not empty.
Hide FG macro is to hide a graph named "FG" and show graph "F" when cell w6 is empty.
Private Sub Workbook_Open()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Sheets
With ws
If .Range("W6").Value = 0 Then
HideFG
Else
HideF
End If
End With
Next
End Sub
Sub HideF()
'
' HideF Macro
'
'
For i = 1 To ActiveSheet.Shapes.Count
ActiveSheet.Shapes(i).Visible = msoTrue
Next i
ActiveSheet.Shapes.Range(Array("F")).Visible = msoFalse
Application.CommandBars("Selection").Visible = False
End Sub
Sub HideFG()
'
' HideFG Macro
'
'
For i = 1 To ActiveSheet.Shapes.Count
ActiveSheet.Shapes(i).Visible = msoTrue
Next i
ActiveSheet.Shapes.Range(Array("FG")).Visible = msoFalse
Application.CommandBars("Selection").Visible = False
End Sub
This should do what you need:
Private Sub Workbook_Open()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Sheets
With ws
If .Range("W6").Value = 0 Then
HideFG ws
Else
HideF ws
End If
End With
Next
End Sub
Sub HideF(wsht As Worksheet)
For i = 1 To wsht.Shapes.Count
wsht.Shapes(i).Visible = msoTrue
Next i
wsht.Shapes.Range(Array("F")).Visible = msoFalse
Application.CommandBars("Selection").Visible = False
End Sub
Sub HideFG(wsht As Worksheet)
For i = 1 To wsht.Shapes.Count
wsht.Shapes(i).Visible = msoTrue
Next i
wsht.Shapes.Range(Array("FG")).Visible = msoFalse
Application.CommandBars("Selection").Visible = False
End Sub
Instead of just calling HideFG, the loop now calls it with a reference to the sheet that the loop is testing. So when HideFG is called, it 'knows' which sheet to make the changes to.
Notice that I've changed the lines where you attempt to hide the columns. Instead of setting Visible to False, you should set Hidden to True.
--------------------------------------------------------------------------------
You could also remove the need for two Hide procedures and replace them with one, where the column(s) to hide are included in the reference passed:
Private Sub Workbook_Open()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Sheets
With ws
If .Range("W6").Value = 0 Then
HideColumns ws.Columns("F:G")
Else
HideColumns ws.Columns("F")
End If
End With
Next
End Sub
Sub HideColumns(rng As Range)
For i = 1 To rng.Parent.Shapes.Count
rng.Parent.Shapes(i).Visible = msoTrue
Next i
rng.Hidden = msoTrue
Application.CommandBars("Selection").Visible = False
End Sub
A final thought - presumably [W6] can change. Currently there is nothing in this code to unhide the columns if it does. You may need to consider this if changes can be made that result in the value of [W6] changing.
Try this:
Private Sub Workbook_Open()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Sheets
With ws
If .Range("W6").Value = 0 Then
HideFG
Else
HideF
End If
End With
Next
End Sub
Private Sub Workbook_Open()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Sheets
With ws
If .Range("W6").Value = 0 Then
HideFG
Else
HideF
End If
End With
Next
End Sub
Sub HideF()
'
' HideF Macro
'
'
For i = 1 To ActiveSheet.Shapes.Count
ActiveSheet.Shapes(i).Visible = msoTrue
Next i
ActiveSheet.Shapes.Range(Array("F")).Visible = msoFalse
Application.CommandBars("Selection").Visible = False
End Sub
Sub HideFG()
'
' HideFG Macro
'
'
For i = 1 To ActiveSheet.Shapes.Count
ActiveSheet.Shapes(i).Visible = msoTrue
Next i
ActiveSheet.Shapes.Range(Array("FG")).Visible = msoFalse
Application.CommandBars("Selection").Visible = False
End Sub
I don't know why am getting out of range subscript error. When I click on combobox1 and select an item, MaternityForm combobox is populated with worksheets in my workbook. Then I want to hide other worksheets apart from the one selected in MaternityForm. The active sheet will then receive data from userform but I am getting subscript out of range error..
Private Sub Get_Data_Click()
Dim ws As Worksheet
Dim xWs As Worksheet
For Each xWs In Application.ActiveWorkbook.Worksheets
xWs.Visible = True
Next
Set ws = Worksheets(MaternityForm.Value)
Sheets(MaternityForm.Value).Activate
On Error Resume Next
For Each ws In Application.ActiveWorkbook.Worksheets
if ws.Name <> MaternityForm.Value Then
ws.Visible = xlSheetHidden
End If
Next
With Sheets(MaternityForm.Value)
.Range("B3").Value = Me.NameBox.Text
.Range("f3").Value = Me.PaynoBox.Text
.Range("B6").Value = Me.DTPicker1.Value
.Range("B7").Value = Me.DTPicker2.Value
.Range("B17").Value = Me.FirstPayBox.Value
.Range("B18").Value = Me.SecondPayBox.Value
.Range("B25").Value = Me.MonthlyPayBox.Value
.Range("H7").Value = Me.DTPicker3.Value
End With
End Sub
You are confusing your variables ws and xWs.
ws is referring to a specific sheet while xWs is your variable worksheet.
Therefore, your second loop is invalid (This is like saying For Each Sheet1 in Worksheets).
You need to loop through your variable worksheets and compare them to your specific sheet
For Each xWs In Application.ActiveWorkbook.Worksheets
if xWs.Name <> ws.Name Then
xWs.Visible = xlSheetHidden
End If
Next
With that being said, there is no need to loop twice.
Note that ws.Name = MaterityForm.Value will return either TRUE or FALSE. The result of this determines ws.Visible = TRUE/FALSE
Private Sub Get_Data_Click()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Sheets
ws.Visible = ws.Name = MaternityForm.Value
Next ws
With Sheets(MaternityForm.Value)
.Range("B3").Value = Me.NameBox.Text
.Range("f3").Value = Me.PaynoBox.Text
.Range("B6").Value = Me.DTPicker1.Value
.Range("B7").Value = Me.DTPicker2.Value
.Range("B17").Value = Me.FirstPayBox.Value
.Range("B18").Value = Me.SecondPayBox.Value
.Range("B25").Value = Me.MonthlyPayBox.Value
.Range("H7").Value = Me.DTPicker3.Value
End With
End Sub
I am trying to add an Excel sheet named "Temp" at the end of all existing sheets, but this code is not working:
Private Sub CreateSheet()
Dim ws As Worksheet
ws.Name = "Tempo"
Set ws = Sheets.Add(After:=Sheets(Sheets.Count))
End Sub
Can you please let me know why?
Try this:
Private Sub CreateSheet()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets.Add(After:= _
ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
ws.Name = "Tempo"
End Sub
Or use a With clause to avoid repeatedly calling out your object
Private Sub CreateSheet()
Dim ws As Worksheet
With ThisWorkbook
Set ws = .Sheets.Add(After:=.Sheets(.Sheets.Count))
ws.Name = "Tempo"
End With
End Sub
Above can be further simplified if you don't need to call out on the same worksheet in the rest of the code.
Sub CreateSheet()
With ThisWorkbook
.Sheets.Add(After:=.Sheets(.Sheets.Count)).Name = "Temp"
End With
End Sub
Kindly use this one liner:
Sheets.Add(After:=Sheets(Sheets.Count)).Name = "new_sheet_name"
ThisWorkbook.Sheets.Add After:=Sheets(Sheets.Count)
ActiveSheet.Name = "XYZ"
(when you add a worksheet, anyway it'll be the active sheet)
Try this:
Public Enum iSide
iBefore
iAfter
End Enum
Private Function addSheet(ByRef inWB As Workbook, ByVal inBeforeOrAfter As iSide, ByRef inNamePrefix As String, ByVal inName As String) As Worksheet
On Error GoTo the_dark
Dim wsSheet As Worksheet
Dim bFoundWS As Boolean
bFoundWS = False
If inNamePrefix <> "" Then
Set wsSheet = findWS(inWB, inNamePrefix, bFoundWS)
End If
If inBeforeOrAfter = iAfter Then
If wsSheet Is Nothing Or bFoundWS = False Then
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = inName
Else
Worksheets.Add(After:=wsSheet).Name = inName
End If
Else
If wsSheet Is Nothing Or bFoundWS = False Then
Worksheets.Add(Before:=Worksheets(1)).Name = inName
Else
Worksheets.Add(Before:=wsSheet).Name = inName
End If
End If
Set addSheet = findWS(inWB, inName, bFoundWS) ' just to confirm it exists and gets it handle
the_light:
Exit Function
the_dark:
MsgBox "addSheet: " & inName & ": " & Err.Description, vbOKOnly, "unexpected error"
Err.Clear
GoTo the_light
End Function
Try to use:
Worksheets.Add (After:=Worksheets(Worksheets.Count)).Name = "MySheet"
If you want to check whether a sheet with the same name already exists, you can create a function:
Function funcCreateList(argCreateList)
For Each Worksheet In ThisWorkbook.Worksheets
If argCreateList = Worksheet.Name Then
Exit Function ' if found - exit function
End If
Next Worksheet
Worksheets.Add (After:=Worksheets(Worksheets.Count)).Name = argCreateList
End Function
When the function is created, you can call it from your main Sub, e.g.:
Sub main
funcCreateList "MySheet"
Exit Sub
Try switching the order of your code. You must create the worksheet first in order to name it.
Private Sub CreateSheet()
Dim ws As Worksheet
Set ws = Sheets.Add(After:=Sheets(Sheets.Count))
ws.Name = "Tempo"
End Sub
thanks,
This will give you the option to:
Overwrite or Preserve a tab that has the same name.
Place the sheet at End of all tabs or Next to the current tab.
Select your New sheet or the Active one.
Call CreateWorksheet("New", False, False, False)
Sub CreateWorksheet(sheetName, preserveOldSheet, isLastSheet, selectActiveSheet)
activeSheetNumber = Sheets(ActiveSheet.Name).Index
If (Evaluate("ISREF('" & sheetName & "'!A1)")) Then 'Does sheet exist?
If (preserveOldSheet) Then
MsgBox ("Can not create sheet " + sheetName + ". This sheet exist.")
Exit Sub
End If
Application.DisplayAlerts = False
Worksheets(sheetName).Delete
End If
If (isLastSheet) Then
Sheets.Add(After:=Sheets(Sheets.Count)).Name = sheetName 'Place sheet at the end.
Else 'Place sheet after the active sheet.
Sheets.Add(After:=Sheets(activeSheetNumber)).Name = sheetName
End If
If (selectActiveSheet) Then
Sheets(activeSheetNumber).Activate
End If
End Sub
This is a quick and simple add of a named tab to the current worksheet:
Sheets.Add.Name = "Tempo"
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