Hide a worksheet based on username - vba

I already have a macro below that un-hides a worksheet at the click of a button and works okay. However I want this macro to be changed so that ONLY two users (whose usernames are "JSMITH" AND "DTAYLOR") are able to unhide this sheet called "Rates".
If someone else (whose username is not one of the two mentioned above) tries to unhide the sheet, I want Excel to display a message "you're not authorised to open this".
Moreover, I need to make sure that only those two users are able to un-hide in a traditional way without vba (eg by right-clicking on a visible worksheet tab and choose Unhide or from any worksheet tab, choose Format, Sheet, and then Unhide).
Can you please advise how to modify the following code to do the all the things described above?
Sub Hide_AllRatesSheet()
Worksheets("Rates").Visible = False
ThisWorkbook.Sheets("Names").Activate
End Sub

Note: you could use xlSheetVeryHidden property to allow unhiding it only from code (and not by mouse right-click).
Try something like the code below:
Sub Hide_AllRatesSheet()
Select Case Environ$("username") '<-- check username
Case "JSMITH", "DTAYLOR"
If ActiveSheet.Name <> "Rates" Then '<-- make sure "Rates" is not the ActiveSheet
Worksheets("Rates").Visible = False
Else
ThisWorkbook.Sheets("Names").Activate
Worksheets("Rates").Visible = False
End If
Case Else
MsgBox "you're not authorised to open this"
End Select
End Sub

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.

Excel Userform to only show if linked worksheet is active

hoping someone can help. I'm very new to VB code.
I'm building a set of Userforms where the data input is linked to various different worksheets. What i want is for my Userform Continue command buttons to only proceed to a certain Userform if the corresponding worksheet is active.
Eg My "Buildings" Userform must only display if Sheet "Buildings" is active on the workbook.
If Sheet "Buildings" is not active then the code must look for the next active sheet and go to the Userform that is linked to that sheet.
Eg If Sheet "Contents" is active on the workbook then the code must show my "Contents" Userform I created.
My first Userform asks the user to select which worksheets must be active by clicking on Toggle Buttons that activate sheets in the workbook.
From there the user clicks on a "Continue" button and then I need my code to look at which sheets are active.
I have this so far but I know its incorrect...
Private Sub CommandButton1_Click()
Dim answer As Integer
answer = MsgBox("Have you selected all your sections?", vbYesNo +
vbQuestion, "Selection Query")
If answer = vbYes And Sheets("Buildings") = Active Then
Me.Hide
Buildings_UF.Show
Else
Exit Sub
End If
End Sub
Thanking in advance
Patrick
UserForm.Show will stop the sub execution while the userform is opened, so the following code should suffice (untested code):
If answer = vbYes Then
Me.Hide
If Worksheets("Buildings").Visible then Buildings_UF.Show
If Worksheets("OtherSheet").Visible then OtherSheet_UF.Show
...
End If

Hide/Unhide sheets using username

I just want to ask if it's possible to create a VBA that detects the identity of the person opening the workbook using Environ$("username") and using that I can hide some of the worksheet and unhide other worksheet that only that person can see?. Then if another person opens up the same workbook it will then hide/unhide worksheets for that other person.
Example of what you want (for educational purposes only):
Private Sub Workbook_Open()
Select Case Environ("username")
Case "bloggsj"
Sheets(1).Visible = False
Sheets(2).Visible = True
Case "doej", "murphyp", "manm"
Sheets(2).Visible = True
Sheets(1).Visible = False
Case Else
'// Unknown, close workbook
ThisWorkbook.Close False
End Select
End Sub
Important: As already mentioned in the comments, this is not a secure way of protecting data, two quick reasons as an example:
The Environment variable "username" can easily be changed which would trick the code into thinking that the person is a different user.
The Workbook_Open event can be easily bypassed by holding the shift button when opening the file.

Hide specific sheets when closing workbook

I'm creating some VBA code which should do the following:
Users press a button a are required to input a code.
When the input the correct code the team relevant code they get access to certain sheets.
The sheets they get access to differs according to the team number and code they enter. So when they enter he password "banana": the sheets "Team_1" & Team_1_sub become visible.
I now created the following code to achieve this:
Sub filter_tabs()
Dim answer As String
answer = InputBox("Please enter your password")
If answer = "Password" Then
MsgBox "Correct, je krijgt nu de goede tabs te zien!"
Worksheets("Team_1").Visible = True
Worksheets("Team_1_sub").Visible = True
Else
MsgBox "Wrong password"
End If
End Sub
Two questions about the code above:
When the users close the document all sheet should "disappear" again. Does anybody know how to do this? So when opening the document sheets "Team_1" and "Team_1_sub" should be be standard
Worksheets("Team_1").Visible = False
Worksheets("Team_1_sub").Visible = False
Could you guys give me some feedback on whether the procedure I follow above (different if statements where users are prompted for a password and then get to see certain tabs) is the most efficient one to reach my goal? End goal is to make sure certain team leader can only see certain sheets.
Here for setting visible false, you can use Workbook_BeforeClose method as follow:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Worksheets("Team_1").Visible = False
Worksheets("Team_1_sub").Visible = False
'must save, if not save, it is not effect.
Me.Save
End Sub
Reference for that method is here.
One thing is that this method must have in the ThisWorkBook module.
For next question, you should say more like, which sheets for which user and password. Because you code is enough for your question. It can use for your requirement.
As you aren't using passwords you should at least make the sheets VeryHidden rather than Hidden - much harder for the average user to unhide.
The Me.Save proposed by the other answer also isn't necessary.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
On Error Resume Next
Worksheets("Team_1").Visible = VeryHidden
Worksheets("Team_1_sub").Visible = VeryHidden
End Sub
ad 1)
you best use a Workbook_BeforeSave() routine to code the hiding of all sheets ... in the VBAProject view you find this under ThisWorkbook
ad 2)
The code you post looks very nice - my point of concern would be the hard coding of user names vs. sheet names. I would consider putting this in a sheet/table using headers /code/ /sheetname/ ... this way you can adapt your logic at any time without having to modify the code.
With such a table at hand (in an all time hidden sheet if need be) you traverse it (one single piece of code) and - upon code entering - you unhide If CodeInTable = CodeEntered ... in the other case you unconditionally hide that sheet ... because hiding/unhiding differs only by 2 simple conditions.

VBA to protect an Excel sheet but allow sort, autofilter, charts, copy

My workbook consists of almost 25 sheets, I want to protect 11 sheets. My criteria for protecting are as follows:
1. User cannot delete or modify any cell
2. User should be able to use SORT, AUTOFILTER, drop down selection from COMBO BOXES
3. Most of the sheets contain charts, they should be updated as per the user selection
4. User should not be able to see the formulas in the formula bar
5. User should be able to copy the data
I have tried all the general options in Excel, which does all the above work, but they leave the cells unlocked, which means user can delete the contents
Thus I hope this can be achieved only by a macro, please help.
I have tried all the general options in Excel, which does all the above work, but they leave the cells unlocked, which means user can delete the contents
Since every thing else works for you, I will not try to address those. With already what you have, add this code in the worksheet code area
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo Whoa
Dim rng As Range
Application.EnableEvents = False
For Each rng In Target
If rng.Value = "" Then
Application.Undo
Exit For
End If
Next
Letscontinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume Letscontinue
End Sub