VBA VeryHidden multiple tabs - vba

I have done research and for whatever reason I cannot get this simple code to work correctly. Simply put, I am trying to xlveryhidden 5 tabs, but I receive run-time error 1004. If anything, it would be nice to change from the Sheet names to code names in case I change the tab names:
Sheet1 - Calculations
Sheet2 - LY Rates
Sheet3 - TY Rates
Sheet4 - Client Details
Sheet5 - Census
Sub VeryHiddenTabs()
Sheets(Array("Calculations", "LY Rates", "TY Rates", "Client Details", "Census")).Visible = xlVeryHidden
End Sub

I was able to use this to set my sheets to .Visible = False.
Sub HideMySheets()
Sheets(Array(Sheet1.Name, Sheet2.Name, Sheet3.Name, Sheet4.Name, Sheet5.Name)).Visible = False
End Sub
Unfortunately, it turns out you are not allowed to use this method to set them to .Visible = xlVeryHidden. Instead you have to do it on a per-sheet basis, using #Ibo's method.

Based on what you have provided it seems you are trying to make all of the sheets very hidden, you cannot do this. You MUST have at least one VISIBLE sheet in the workbook.
Additionally, to use VBA to make sheets very hidden not using the sheet names, you should then use the sheet indexes or sheets' code name. Sheets code name cannot be change using the interface so the code would work with whatever the sheet name is. To change the sheets' code name, go to VBE (ALT + F11), double click on the sheet you want and change the name, which is the first item in the properties window, if you don't see the properties window click F4. Let's say you change the code name of the sheet to mySht1 then you can do:
mySht1.Visible = xlVeryHidden
if you use the index of the sheets to change the visibility you can do this:
ThisWorkbook.Sheets(1).visible=xlVeryHidden
if you want to use this method, you need to always have one visible sheet so you have to create a sheet and then run this code:
Sub VeryHiddenTabs()
For i = 1 To ThisWorkbook.Worksheets.Count - 1
ThisWorkbook.Worksheets(i).Visible = xlVeryHidden
Next
End Sub
since you have already had the sheet you have mentioned, then Excel will make all of the very hidden. The above routine will keep the last created sheet visible and the rest very hidden.

Related

Use a part of macro code independently

I have one doubt!
I have a code for consolidation of 22 sheets in a workbook.
Now I want to prepare separate buttons for each sheet so that if the user wants they can consolidate only sheets required by them and not all 22 sheets.
I only know the way by creating 22 separate module having part of the codes related to each sheet. Is there any other concise way to do it which do not make me prepare 22 separate modules?
Code example:
sheets("AT").select
"whatever code that was required"
Sheets("DE").select
"whatever code that was required"
and so on....
Do let me know if question is not clear.
You only need a single module. When you click a button on a sheet it will be on the activesheet. Therefore you will only need to act on the activesheet and not every sheet in the workbook.
If I was doing the job I would create a userform with a List of worksheet names that the user can select and then the module will step through each selected worksheet name in the list and do whatever actions you need. A checkbox for whole workbook action would also be useful.
Make a new Userform with a commandbutton and also a list box called "myListBox" and ensure that the MultiSelect property is set to multi and not single then add the following code. This will step through each sheet in the workbook and adds the name to the listbox. Once you select a number of names and click the command button it will print the selected names to the Immediate window
Private Sub UserForm_Initialize()
Dim wks As Worksheet
For Each wks In ActiveWorkbook.Worksheets
Me.myListBox.AddItem wks.Name
Next
End Sub
Private Sub CommandButton1_Click()
For i = 0 To myListBox.ListCount - 1
If myListBox.Selected(i) Then
Debug.Print myListBox.List(i)
End If
Next i
End Sub

Stop Excel from changing active sheet on Sheets.Visible = True command

I have a large workbook with many sheets used for background calculation that I hide when they are not in use. The workbook is locked down (no ribbon, sheet tabs, formula bar, etc) so it cannot be tampered with when it is in use.
In Excel 2010, everything went smoothly and the active sheet was not changed, but now in Excel 2016 the following Sub changes the active sheet to the "CompCalc" sheet which leaves the user with no way to return to the sheet they need to be on to use the workbook.
Sub MakeSheetsVisible(Status As Boolean)
Dim VarSubName As String
VarSubName = "MakeSheetsVisible"
'***********************************************************
ProtectSheets (False)
Sheets("DATA_INPUT").Visible = Status
Sheets("RAW_DATA").Visible = Status
Sheets("MASTERHISTORY").Visible = Status
Sheets("CompCalc").Visible = Status
'Sheets("Event_Enter").Visible = Status
Sheets("Raw_Chart_Data").Visible = Status
End Sub
This Sub is called at the end of a Sub that is called from another Sub which can be triggered 1 of 2 ways, on a button press or ListView double click. The active sheet is only changed in the above routine when the button is used to call the initial Sub and when the routine is ran continuously (not stepped through with F8).
I can work around this issue by checking the original active sheet at the beginning of the routine and setting it back to the original at the end, but I would like to know why this is happening and if there is a way to stop it without a workaround. Any help is appreciated
It's an annoying bug in Excel 2013/2016 and as far as I know, there is no fix. A workaround I use is:
Set CurrentSheet = ActiveSheet
'Instructions here
CurrentSheet.Activate
I only ever use active sheet if it's needed for something specific. (as per MatthewD)
But surely when you've set all your sheets to visible, you can add another line to make the sheet you want to be active?
Sheets("The one you want").Activate
would do the job? (or maybe .select?)

Formulas not updating when macro changes sheet name

I have written a macro to change a sheet name depending on what a user inputs. This works fine, my problem is that usually when you change a sheet name manually, the formulas that relate to the changed sheet all update.
This isn't happening when the macro changes the sheet name. Is there anything I can do to make this happen?
Since the sheet you are renaming is not the active sheet, you will need to reference the new sheet in your macro. Try this:
Sheets(NewName2).EnableCalculation = False
Sheets(NewName2).EnableCalculation = True
So I do this with formulas/advanced lookups embedded in a template sheet using the following two-step process:
Sheets("Template").Copy After:=Sheets(Sheets.Count) 'this is putting it at the very end of my document based upon the count of tabs
Sheets(Sheets.Count).Name = sName ' we then rename the sheet, because you want it created, then you want to rename it, as it will then allow for all formulas to refresh.

Hyperlink directs to hidden row

I have a workbook that has 2 sheets. Sheet 1 has hyperlinks to several different cells in Sheet 2. The issue is that there are filters in Sheet 2 that will hide rows, so when you try to follow the hyperlink from Sheet 1, the row is hidden and you can't see the target. I'm trying to figure out how to do the following:
On clicking a hyperlink, determine the target row in Sheet 2
If target row is hidden, unhide the target row in sheet 2, then follow the hyperlink.
It can stay unhidden after the hyperlink is followed, I'm fine with that. I've struggled with this for the past several days, and have come up with nothing successful. I've tried the "Followhyperlink" function, but I think this is too late - it's already followed the hyperlink, so unhiding the row at that point is too late.
Any suggestions? I'm stumped!
FollowHyperlink is indeed the event handler to use. Put this code in the worksheet module for Sheet1:
Option Explicit
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
Dim hyperlinkParts() As String
If ((Target.Type = msoHyperlinkRange) And (Target.SubAddress <> "")) Then
If (InStr(Target.SubAddress, "!") > 0) Then
hyperlinkParts = Split(Target.SubAddress, "!")
If ((Left$(hyperlinkParts(0), 1) = "'") And (Right$(hyperlinkParts(0), 1) = "'")) Then
hyperlinkParts(0) = Mid$(hyperlinkParts(0), 2, Len(hyperlinkParts(0)) - 2)
End If
Worksheets(hyperlinkParts(0)).Range(hyperlinkParts(1)).EntireRow.Hidden = False
End If
End If
End Sub
This checks that the hyperlink corresponds to a Range object then splits the target address into the sheet name and the specific cell(s). It then unhides the row(s) which correspond to the target address.
The check for the subaddress being empty is needed for hyperlinks to an external workbook where no particular cell is specified
edit: this approach won't work for hyperlinks to named ranges and I've altered the code to avoid getting an error message with that kind of hyperlink
edit2; code revised to deal with worksheet names containing spaces which were previously causing an error

How to capture worksheet being added through Copy/Paste in Excel VBA

I am trying to capture worksheets being copied in to a workbook from another workbook.
Workbook_NewSheet event does not trigger when the sheets are copied from another workbook.
It is triggered only if the user manually inserts them through (Insert->Worksheet menu option), or when you add a new sheet through VBA as ThisWorkbook.Worksheets.Add.
What I am trying to capture is basically a Paste operation which is resulting in a new sheet.
This might be from any of the below user actions:
User copies an existing sheet by dragging it holding Control Key (which adds a new sheet)
User copies sheet/s from another workbook
user moved sheets from another workbook
or any of the below VBA code:
SourceWorkbook.Sheets(“SourceSheet”).Copy Before:=TargetWorkbook.worksheets(“SheetNameIn Target”) 'copy across workbook'
SourceWorkbook.Sheets(“SourceSheet”).Move Before:=TargetWorkbook.worksheets(“SheetNameIn Target”) 'move across workbook'
ThisWorkbook. Sheets(“SheetName”).Copy 'copy within workbook'
If you know any way of capturing this action/macro results within VBA that would be greatly helpful.
Please note that I do not want to avoid such an user action (so i do not want to secure the workbook) but I want to handle the pasted sheet programatically to verify the data, and if the similar sheet already exists then update the existing sheet rather than having same data in two sheets.
When a sheet is copied, its name will always end with "(2)", or at least ")". You could check on that like this
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
If Sh.Name Like "*(2)" Then
Application.DisplayAlerts = False
Sh.Delete
Application.DisplayAlerts = True
End If
End Sub
The SheetActivate event will fire under all of those circumstances. Obviously it will fire under a lot of other circumstances too. This sounds like a royal pain, but you could maintain your own collection of worksheets and compare your collection to the ThisWorkbook.Sheets collection to see if something was added/deleted.
If you're trying to prevent it, you might consider protecting the workbook structure instead of doing it in code.
The way I have it implimented is
Private Sub Workbook_WindowActivate(ByVal Wn As Window)
ToggleMenuOptions False, 848, 889
End Sub
Private Sub Workbook_WindowDeactivate(ByVal Wn As Window)
ToggleMenuOptions True, 847, 848, 889
End Sub
Public Function ToggleMenuOptions(bToggle As Boolean, ParamArray ControlID() As Variant) As Boolean
'848 Move or Copy Sheet...
'889 Rename Sheet
'847 Delete Sheet
On Error GoTo lblError
Dim oControl As CommandBarControl, oControls As CommandBarControls, iControl As Integer
If IsMissing(ControlID) Then
ToggleMenuOptions = False
Exit Function
End If
For iControl = LBound(ControlID) To UBound(ControlID)
For Each oControl In Application.CommandBars.FindControls(ID:=ControlID(iControl))
oControl.Enabled = bToggle
Next
Next
ToggleMenuOptions = True
Exit Function
lblError:
If Err.Number Then
ToggleMenuOptions = False
Exit Function
End If
End Function
Private Sub Workbook_NewSheet(ByVal Sh As Object)
MsgBox "Please use Add New Project option in custom Toolbar to add new sheets!!", vbExclamation, "Not Supported"
Application.DisplayAlerts = False
Sh.Delete
Application.DisplayAlerts = True
End Sub
So my users wont be able to rename, add or delete sheets. This is working pretty well for now.
The only way I can think of doing this without maintaining a separate sheets collection is to maintain a static array of sheet names (or sheet codenames) and compare this to the actual sheets in the workbook each time the SheetActivate event fires to detect any additions. If you don't want to/can't keep the list in an array you could always use a hidden sheet to store the list. Whether this is any more or less of a pain than maintaining a separate collection is debatable :)
I am working on something similar but cannot block any of the user menu actions. I have sheets whose type are important - each sheet is either a Master or Slave - each Master sheet sums over the Slave sheets beneath it and I need to keep these formula clean.
Rather than maintain a list of sheets in an extra hidden sheet, I am defining 2 hidden names on each sheet recording the offset of the index of the Sheet to its linked Master sheet, and a reference to the linked Master sheet. So if my sheet is (say) +2 tabs from its Master sheet, then on Sheet activate/deactivate (not sure which of these is better to track at this stage) this offset will have changed if anything gets inserted, deleted or moved. This covers most or all of the events that would arise from moving or copying sheets.
If the sheet has been moved, I cycle through the workbook and calculate new Master/Slave index references for every sheet.
Will post code when I get this reasonably stable but it seems like a scheme that would work in a wide variety of circumstances.