Hide/Unhide sheets - VBA - vba

I have a worksheet containing 15 different sheets. I want a "main menu" sheet from where I can just click a button and then be redirected to the chosen sheet, while keeping all the other sheets hidden. From the chosen sheet I want to be able to go back to the "main menu" sheet again and still keep everything hidden. Thus, only one sheet will show at the time.
My problem is the following;
The VBA code that I use is working perfectly, but sometimes it shows the error
Run time error '1004': Method 'Visible' of object '_Worksheet'failed
, and when I go to debug it shows the following debug screen.
As mentioned the code works "perfectly", but sometimes the run time error 1004 pops up. What am I doing wrong? The code is the following;
Sub Button8_Click()
Sheet3.Visible = xlSheetVisible
Dim sh As Worksheet
For Each sh In ThisWorkbook.Sheets
If sh.Name <> "practice group - mtd" Then
sh.Visible = xlSheetHidden
End If
Next sh
End Sub

A faster workaround to avoid looping all sheets:
keep the name of the visible sheet somewhere hidden in main menu sheet.
(in a hidden cell, with FIXED location).
Upon button click, if selection different than visible one, unhide selected, hide previous sheet, update main menu.

Sheets("Your Sheet Name").Visible = False

Related

VBA VeryHidden multiple tabs

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.

Assign macro to button that executes the macro on the designated row of where the button is located.=

I need help with VBA with a code where a button pressed executes the assigned macro, where the macro is assigned to execute where the button was pressed.
Basically, I created a tracking workbook where I usually input a new "task" via macros, this adds a new row and a new button by the row.
The problem I am having is that I want to use the same macro (once task is completed, it cuts and pastes into a "history" sheet) for the specific row a button is located.
How can I do this? Is this actually possible? Below is the step by step of my thoughts
Press "AddTask" button = creates a new row with data input from user with "Completed" button on the same row
Tie the "Completed" button to the row that was added so when Macro "Complete" runs, it will only run specifically to the row of where the button was pushed.
This will help because maybe I finish task# 53 (row 53) first before task# 41 (row 41), so I want to delete row 53.
Macros and VBA is what I need.
You can use Application.Caller to determine what called a Sub. In the case of a Form button it returns the name of the button as a string. (Refer online help for full details). Then use the ActiveSheet Buttons collection to retrieve the button, and TopLeftCell to get the location on the sheet. Error handling is required to gracefully exit if the Sub is called from other sources.
Sub Complete()
Dim rng As Range
If TypeName(Application.Caller) <> "String" Then Exit Sub
On Error Resume Next
Set rng = ActiveSheet.Buttons(Application.Caller).TopLeftCell.EntireRow
On Error GoTo 0
If rng Is Nothing Then Exit Sub
' rng now refers to the row that the clicked button is on
'... rest of your code
End Sub

Activating a different worksheet using VBA does not change the focus on it permanently

I want to select and modify different worksheets programmatically every time the workbook is saved. At the end however, I want to set the focus on a particular worksheet so that the workbook is saved with that particular worksheet in focus. What I'm noticing is that whenever the code executes it activates the worksheets, modifies them but at the end it goes back to the worksheet that I had selected before running the code.
Here's my code:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Sheets(1).Activate
Debug.Print Sheets(1).Name
End Sub
The code above is executed in an empty, local workbook with 2 empty worksheets
Sheet1 and Sheet2. Whenever I save the workbook with Sheet2 selected, I see that it is indeed activated because the console log prints Sheet1, in the workbook however, the selected worksheet remains Sheet2.I'm using SAP's BusinessObjects Analysis but as noted above, the workbook is a local macro-enabled workbook that is not saved on the SAP NetWeaver platform.
Is it possible for me to permanetly set the focus to a different worksheet so that it's visible in the workbook?
Thanks
EDIT:
Oh no!!! I have the annoying problem of inconsistent behavior with the different save buttons once again and that is yet to be resolved! I just realized that if I save through the workbook save button the sheet permanently changes, however when I save through the code editor it doesn't. The previous problem I had experienced was on workbooks saved on SAP NetWeaver where VBA code is not executed through the workbook save button but is, through the code editor save button. I guess I will have to log an Oss with SAP for this inconsistency.
What you are saying is only possible, if someone has written:
Private Sub Worksheet_Activate()
Sheets(2).Activate
End Sub
At Worksheets(1).
Otherwise, the code you are using:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Sheets(1).Activate
Debug.Print Sheets(1).Name
End Sub
should activate the first Sheet and it should not be changed later.
I have no idea where Sheet2 is compared to Sheet1.
You say
The code (above) is executed in an empty, local workbook with 2 empty
worksheets Sheet1 and Sheet2. Whenever I save the workbook with
Sheet2 selected, I see that it is indeed activated because the console
log prints Sheet1, in the workbook however, the selected worksheet
remains Sheet2
Your code doesn't do anything to a sheet called Sheet2. It only looks at the first sheet in the tab order - the sheet could be called anything.
It activates the first sheet and then puts the name of the first sheet in the immediate window.
This code will select the sheet with the tab name Sheet2, it will then put the name of the activesheet (Sheet2) in cell A1 of the sheet with the tab name Sheet1.
Finally it selects the sheet with the codename Sheet3 (The codename is the name not in brackets in the Project Explorer).
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
With ThisWorkbook
.Worksheets("Sheet2").Select
.Worksheets("Sheet1").Range("A1") = ActiveSheet.Name
End With
Sheet3.Select
End Sub
Just use following code:
Sub activateSheet(sheetname As String)
'activates sheet of specific name you want.
Worksheets(sheetname).Activate
End Sub
then for select another sheet:
Sub activateSheet(sheetname As String)
'selects sheet of specific name you want.
Sheets(sheetname).Select
End Sub
Regards
Xsi

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?)

Can I set a cell in a sheet as the selected one, without activating the sheet?

In a workbook I am creating I have created a procedure which loops through several worksheets clearing out some ranges++, preparing the workbook for a new year. However, I wanted to set a given cell in the sheet, e.g. F5 as the active one before moving on to the next sheet, as that's where it's most likely the users will start inputting data when they move to the sheet.
However, trying to put both .Select and .Activate into line 5 of the code below fails with Select / Activate method of Range class failed.
For Each ws In ThisWorkbook.Worksheets
If InStr(1, ws.CodeName, "Veke_", vbTextCompare) > 0 And Len(ws.CodeName) = 7 Then
Call lås_opp_ark(ws)
Call oppdater_ark_for_nytt_år(ws, førsteSkiftIVeka(dato))
ws.Range("F5").Select
Call lås_ark(ws)
End If
Next ws
Trying to figure out why this didn't work I eventually came across this documentation-page from Microsoft which states that:
Before you can use the Selection property successfully, you must activate a workbook, activate or select a sheet, and then select a range (or other object) using the Select method.
Which I take to mean that using Select on anything but the active worksheet won't work. The page doesn't explicitly state anything about Activate, but I assume the reasons for the errors I'm getting to be the same.
Now, my question is this - is there any way to set the active cell in a nonactive worksheet without activating it first? If not, would activating each sheet in the workbook to set the active cell be very resource intensive? I guess I could check the latter myself, but any input would be interesting too.
No need to select the cell, instead activate it. Try this:
Replace:
ws.Range("F5").Select
with this:
Application.Goto ws.Cells(1), 1 'This activates ws and scrolls to place cell `A1` at the top of the window
Application.Goto ws.Range("F5") 'This selects Cell `F5`
see Application.Goto Method (Excel)