VBA Hide all sheets that aren't being used in workbook - vba

I have many sheets in a workbook. I have a main sheet/"form" called "JE" and on that sheet there are buttons and macros that lead to other sheets in the workbook. But, the intention is for other users, not myself, to use the workbook. So, I would only like the sheet that is being used to be visible at any given time. At no time do I want more than 1 sheet to be visible by the user. The user can navigate the workbook mainly thru clicking buttons and certain cells in select sheets that will allow them to navigate throughout the entire workbook. I have tried this by adding code into 'ThisWorkbook' module but it doesn't seem to working as I'd like. When I navigate to one sheet and back to another, some sheets remain visible when I'd like them to be hidden so I'm unsure of what other modifications I can make to code below to get my desired result. If anyone can offer up any modifications or changes I can make to accomplish this, I'd really appreciate it.
UPDATE:
I have added this code to my 'ThisWorkbook' Object:
Option Explicit
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim MySh As Worksheet
For Each MySh In ThisWorkbook.Worksheets
If MySh.Name <> Sh.Name Then MySh.Visible = 0
Next MySh
End Sub
but, when I go to double-click values that usually populate cells in my main sheet ("JE") I get a run-time 1004 error. The values still populate the main sheet but it no longer navigates back to the main sheet as I'd like.
If anyone knows of a solution or a mod I can make, I'd really appreciate it.

The code is nice. Simply put it in the Workbook part of the VBA project:
Option Explicit
Private Sub Workbook_Open()
Dim MySh As Worksheet
For Each MySh In ThisWorkbook.Worksheets
If MySh.Name = ActiveSheet.Name Then MySh.Visible = xlSheetHidden
Next MySh
End Sub
The ThisWorkbook part is here:
In general, I use always something similar, when I am starting an Excel application. I define two Arrays with Visible and Invisible Worksheets and I iterate over them, making them either visible or not visible. Like this:
Option Explicit
Public Sub HideNeeded()
Dim varSheet As Variant
Dim arrVisibleSheets As Variant
Dim arrHiddenSheets As Variant
arrVisibleSheets = Array(Sheet1)
arrHiddenSheets = Array(Sheet2, Sheet3)
For Each varSheet In arrVisibleSheets
varSheet.Visible = xlSheetVisible
Next varSheet
For Each varSheet In arrHiddenSheets
varSheet.Visible = xlSheetVeryHidden
Next varSheet
End Sub
xlSheetVeryHidden makes it possible to unhide it only from the VB Editor. Otherwise you need xlSheetHidden.

It should be Workbook_SheetActivate:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim MySh As Worksheet
For Each MySh In ThisWorkbook.Worksheets
If MySh.Name <> Sh.Name Then MySh.Visible = 0 'zero - false, 1 - true, 2 - very hidden
Next MySh
End Sub

Sub HideInactive()
Set theActiveSheet = ActiveSheet
For Each Sheet In ThisWorkbook.Worksheets
If Sheet.Index <> theActiveSheet.Index Then Sheet.Visible = False
Next
End Sub
I 've test the code. Thank you for reading.

Related

make VBA form only read one workbook when other workbooks are open

I'm new here, I've read the rules, but please inform/forgive me if I have missed anything or posted incorrectly.
Now, to my problem:
I have created my first form in Visual Basic that has allowed me to create a searchable and editable database.
Upon allowing colleagues to test the form, I quickly released that they cannot use any of their other Excel workbooks that they have open (The other workbooks are not related in any way to my workbook/form).
After some researching, I found that I can add (vbmodeless) to the button that opens the form. This then allows the team to flick between the form and use other workbooks to look at other information and then go back onto the form.
The only problem I have now, is that when they go back to the form, it reads an error in the macros, because its trying to use the macros on another workbook and not my workbook.
In short, is there any way you can use (vbmodeless), but lock the forms Macros to my specific workbook?
If anyone can solve this riddle, they will be my best friend. I'm aiming to have this ready for its presentation next week on the 6th of March.
Thank you.
Well, let's say like tigeravatar, you haven't declared a workbook :
Dim ws As Workbook
ws = ActiveWorkbook
'instead of
Sheets("Sheet1").Range("A3") = 5 'for example
'you would have
ws.Sheets("Sheet1").Range("A3") = 5
You can also work with the sheets itself, but you'll have to use parameters and search each :
Dim ws As Workbook
Dim sh, SpecificSheet1, SpecificSheet2 as Object 'To manipulate sheets
Dim Name_Sheet1, Name_Sheet2 As String
Set ws = ActiveWorkbook
Name_Sheet1= "Sheet1"
Name_Sheet2= "Sheet2"
For Each sh In Sheets
If InStr(sh.Name, Name_Sheet1) = 1 Then
Set SpecificSheet1 = sh
ElseIf InStr(sh.Name, Nom_Ref_Donnees) = 1 Then
Set SpecificSheet2 = sh
End If
Next
'Instead of :
Sheets("Sheet1").Range("A3") = 5 'for example
'You would use :
SpecificSheet1.Range("A3") = 5
According to your way of using subs, theses both solutions may need to use Public declaration of theses objects :
Option Explicit
Public ws As Workbook
Public SpecificSheet1, SpecificSheet2 as Object 'To manipulate sheets
Sub yoursub()
Dim sh, SpecificSheet1, SpecificSheet2 as Object 'To manipulate sheets
Dim Name_Sheet1, Name_Sheet2 As String
If (IsEmpty(ws)) Then
Set ws = ActiveWorkbook
Else
ws.activate
End If
Name_Sheet1= "Sheet1"
Name_Sheet2= "Sheet2"
For Each sh In Sheets
If InStr(sh.Name, Name_Sheet1) = 1 Then
Set SpecificSheet1 = sh
ElseIf InStr(sh.Name, Nom_Ref_Donnees) = 1 Then
Set SpecificSheet2 = sh
End If
Next
End Sub

How to disable add sheet button in Excel with VBA?

I have a workbook I would like to disable the Add New Sheet button that is next to the tabs. I have searched and found the following that disable the insert options on the workbook book which is great.
Application.CommandBars("Ply").FindControl(, 945).Enabled = False
Application.CommandBars("Insert").Controls(4).Enabled = False
But I have yet to find the command for the Add New Sheet button. Is there a place that lists all these options or a tool I can use to identify the control or button.
The workbook is shared so automatically deleting the sheet on creation will not work.
Protect Structure does not work either and throws the following error:
In the ThisWorkbook code sheet, paste the following.
Option Explicit
Private Sub Workbook_NewSheet(ByVal Sh As Object)
Application.DisplayAlerts = False
Sh.Delete
End Sub
Any new (or copied) worksheet that is created is instantly deleted.
This isn't a proper solution to your actual problem, but it will give the illusion of doing what you want...
In the ThisWorkbook module, add this to instantly hide any new sheets with 'DeleteThisSheet' in cell A1
Private Sub Workbook_NewSheet(ByVal Sh As Object)
Sh.Cells(1, 1) = "DeleteThisSheet"
Sh.Visible = xlSheetVeryHidden
End Sub
Obviously, this will clutter up the workbook with hidden sheets, so you can clear them out from time to time using this code to switch off sharing and delete the hidden sheets.
Sub removeSheets()
Dim ws As Worksheet
' Turn off sharing
Application.DisplayAlerts = False
If ActiveWorkbook.MultiUserEditing Then
ActiveWorkbook.ExclusiveAccess
End If
' Delete veryhidden sheets with delete code
For Each ws In ThisWorkbook.Sheets
If ws.Visible = xlSheetVeryHidden And ws.Cells(1, 1) = "DeleteThisSheet" Then
ws.Visible = xlSheetVisible
ws.Delete
End If
Next ws
' Turn sharing back on
If Not ActiveWorkbook.MultiUserEditing Then
ActiveWorkbook.SaveAs ActiveWorkbook.Name, accessmode:=xlShared
End If
Application.DisplayAlerts = True
End Sub
As I say, it's not ideal, but may at least serve your purpose, although probably won't stand up to many people repeatedly attempting to add new sheets. You could possibly add a msgbox to the newssheet code to say something along the lines of 'This action has been disabled' to stop them retrying. I'll keep an eye on this thread to see if anyone comes up with a proper solution, it's always good to learn something new.
Not sure if this solves the issue:
Application.CommandBars("Insert").Controls(4).Visible = False
This uses Visible property.

Excel VBA to Work Across Workbooks

I am very new to VBA coding and don't have very good understanding of what I am doing to be honest. But here I go.
I am looking to see if:
Can VBA codes have dyname values? So instead of the code saying execute on a set sheet (e.g "Sheet1") that value changes depending a value in a certain cell.
To trigger a VBA on another workbook. For example I want to run a VBA from Workbook A that triggers a VBA on Workbook B.
To fully explain I want to open Workbook A (and Workbook B if needed, it doesn't matter) and click a button that runs a VBA on Workbook B but on a certain Sheet depending on the value of a cell in Excel A (if the cell says "sheet3" the VBA runs on "sheet3" on Workbook B). I also want cells in Workbook A to reference cells in Workbook B but the the sheet name to by dynamic. For example I have pasted the basic cell reference bellow but instead of having Sheet1 I want it to change depending on the value in a cell.
='[Workbook B.xlsx]Sheet1'!$A$4
I know this sounds very complicates and confusing, but if I could get any help that would be greatly appreciated.
Sub ReportStepOne()
Dim myRow As Long
myRow = 4
Rows(myRow).Value = Rows(myRow).Value
Dim rng As Range
Set rng = Range("A4:AC200")
rng.Cut rng.Offset(1, 0)
Range("A1:AC1").Copy Range("A4:AC4")
End Sub
I want to:
edit this code to make it fire on a certain sheet
make it so the sheet name is referenced to whatever is in cell A o Sheet2 in Report.xlsm.
Run a macro in Report.xlsm that runs the above script (which is called "StepOne" in a file called "Historical Data.xlsm"
The code below takes the value of cell A4 on sheet2 in Reports.xlsm and sets the ws variable to the sheet in Historical data.xlsm which is then used for the rest of the code. If possible I'd advise against having your subs spread out over multiple projects but that is just my opinion. I think it is easier to use proper referencing like below.
Since you want a button trigger on the Report.xlsm I'd suggest moving this code to that workbook. If properly referenced it you can open, edit, save and close any workbook from a single project which again, in my opinion is easier than calling subs in a different project.
Sub ReportStepOne()
Dim wbHis As Workbook, wbRep As Workbook
Dim strWsName As String
Dim ws As Worksheet
Set wbHis = Workbooks("Historical data.xlsm")
Set wbRep = Workbooks("Reports.xlsm")
strWsName = wbRep.Worksheets("Sheet2").Cells(4, 1)
Set ws = wbHis.Worksheets(strWsName)
With ws
With .Rows(4)
.Value = .Value
End With
With .Range("A4:AC200")
.Cut .Offset(1, 0)
End With
.Range("A1:AC1").Copy .Range("A4:AC4")
End With
End Sub
To trigger a VBA on another workbook
Option Explicit
Sub RunVBA()
Dim xlApp As Excel.Application
Dim xlWorkBook As Workbook
Set xlApp = New Excel.Application
Set xlWorkBook = xlApp.Workbooks.Open("C:\Users\Om3r\Desktop\Book1.xlsm")
xlApp.Visible = True
xlWorkBook.Application.Run "Module1.SubName" ' Modulename.Subname
End Sub
To reference worksheet use
Sub CopyRange()
'// From sheet1 to sheet2
Worksheets(2).Range("A1").Value = Worksheets(1).Range("A1").Value
End Sub

I need to insert tab name in cell A1 of every tab with changing tab names

I need to open a worksheet with a fixed name and insert the name of each tab (which will change according to the current date) at the top of the sheet.
I modified some code from a previous answer and had the code working when it did not include the code to open the workbook. Now it flicks through the tabs but doesn't insert the name into Cells(1, 1) and I have no idea why. It also bugs at the end: Run-time error 91, which is less problematic but would be good to fix.
Any tips or advice much appreciated. Below is my current code:
Sub PSOPENTAB()
ChDir "G:\directory"
Workbooks.Open Filename:="G:\directory\filename.xls"
Windows("filename.xls").Activate
ActiveWorkbook.Worksheets(1).Activate
Call nametop
End Sub
Sub nametop()
Dim i As Long
With ThisWorkbook
'exit if Activesheet is the last tab
If .ActiveSheet.Index + 1 > .Worksheets.Count Then
Exit Sub
End If
For i = .ActiveSheet.Index To .Worksheets.Count - 1
.ActiveSheet.Cells(1, 1) = .Worksheets(i).Name
ActiveSheet.Next.Select
Next i
End With
End Sub
You need to reference your objects correctly.
Your problems are:
You use Thisworkbook in your nametop routine. So it will always work on the workbook containing the code.
You can change it to ActiveWorkbook but that may lead you to other problems in the future. See this cool stuff to know more about why to avoid Activeworkbook/Activesheet and the like
Applying what's discussed there, try below code:
Sub PSOPENTAB()
Dim wb As Workbook
Set wb = Workbooks.Open(Filename:="G:\directory\filename.xls")
nametop wb
End Sub
Sub nametop(wb As Workbook)
Dim ws As Worksheet
For Each ws In wb.Worksheets
ws.Cells(1, 1) = ws.Name
Next ws
End Sub
Above code adds the name of the sheet in Cell A1 of every sheet.
Is this what you're trying?

Error-1004 in Excel VBA- Unable to set the visible property of the worksheet class

With the help of Excel forum, I have created a user login form where I have 5 users. Each user can have access to the sheets assigned to him/her only. This is working fine. But now I have protected the "workbook structure" so as to avoid users' adding/deleting sheets. Then I login again, and instead of displaying the login form, the error message pops up in Excel VBA:
Error-1004 Unable to set the visible property of the worksheet class
When I debug the error is highlighted in the following codes where the visible property of the worksheet is set as "True", "False" or "xlSheetVeryHidden".
Private Sub Workbook_Open()
Dim wsSht As Worksheet
Worksheets("Splash").Visible = True
Worksheets("Users").Visible = False
For Each wsSht In Worksheets
If Not wsSht.Name = "Splash" Then wsSht.Visible = xlSheetVeryHidden
Next wsSht
With Worksheets("Splash")
.Visible = True
.Activate
End With
frmLogin.Show
bBkIsClose = False
End Sub
Is there a way to correct this so as I can access the login form as I did prior to password protecting the "workbook structure"?
Here is another concern about this.
You can NOT hide ALL of the worksheets in a workbook. As such if you know you are going to have at least 1 sheet that will ALWAYS be visible, exclude it from the hiding process.
Did you have another Excel Workbook opened at the same time when testing it? There's no explicit reference to the book you're looking for, so in case you run this code having a workbook where the "Splash" sheet is not available, the macro will try to set all sheets to hidden, which may raise this error.
To simulate it, open a new Excel session and run this macro:
Sub test()
Dim oSheet As Excel.Worksheet
For Each oSheet In Worksheets
oSheet.Visible = xlSheetVeryHidden
Next oSheet
End Sub
If I'm not barking to the wrong tree, you'll get the same error.
To solve it, simply add the workbook name into your loop, and it would be like this (obviously, you must ensure that there's a "Splash" sheet, or the error will arise):
For Each wsSht In Workbooks("Mybook.xlsm").Worksheets
If Not wsSht.Name = "Splash" Then wsSht.Visible = xlSheetVeryHidden
Next wsSht
Rgds
You'll have to unprotect and reprotect in code. The downside is that your password will be in the code.
Private Sub Workbook_Open()
Dim wsSht As Worksheet
Me.Unprotect "password"
Me.Worksheets("Splash").Visible = True
Me.Worksheets("Users").Visible = False
For Each wsSht In Me.Worksheets
If Not wsSht.Name = "Splash" Then wsSht.Visible = xlSheetVeryHidden
Next wsSht
With Me.Worksheets("Splash")
.Visible = True
.Activate
End With
frmLogin.Show
bBkIsClose = False
Me.Protect "password", True, False
End Sub
I'm not sure if this is relevant, but I found this question when I was searching for how to hide the last (and only) worksheet. The reason for wanting to do this is because the file is a startup file that contains company-wide macros that should not be edited by the user. I discovered that while the Worksheet needs to be kept open, the Window displaying it does not.
Here's an example:
Sub spork()
Dim x As Workbook
x.Windows.Item(1).Visible = False
End Sub
Now, Excel opens the file with no worksheet visible.
Sometimes there is a "glitch" (a.k.a. "feature" or "bug"), simply returning this error due to no visible reason. Not the worksheet protection, neither the fact that this is the last worksheet visible. To fix the "feature" this worked for me:
Public Sub UnhideAll()
Dim wks As Worksheet
For Each wks In ThisWorkbook.Worksheets
wks.Visible = xlSheetVisible
Next
End Sub