VBA stops working once the sheet is protected - vba

I have a table with filter.
I wrote simple VBA so that when the user pick different option, the VBA will pick the filter and sort the table automatically. It works perfectly.
I then hide, lock and protect the sheet to keep it simple and prevent the user from changing the formulas. But, once the sheet is protected (I ticked and gave permissions for all actions), still the VBA fails to run. If I switched back to "unprotected", everything works again.
I am stuck, hope fellow experts can advise please.
Many thanks!
Simple VBA as below:
Private Sub Worksheet_Change(ByVal Target As Range)
If Range("BF1").Value = "Highest $" Then
Range("A5:CK288").Sort Key1:=Range("BG5:BG288"), Order1:=xlDescending
End If
If Range("BF1").Value = "Nearest end" Then
Range("A5:CK288").Sort Key1:=Range("BC5:BC288"), Order1:=xlAscending
End If
If Range("BF1").Value = "Customer" Then
Range("A5:CK288").Sort Key1:=Range("BE5:BE288"), Order1:=xlDescending
End If
If Range("BF1").Value = "Country" Then
Range("A5:CK288").Sort Key1:=Range("BD5:BD288"), Order1:=xlDescending
End If
If Target.Address = Range("BF2").Address Then
If Range("BF2") = "All" Then
Range("A5").AutoFilter Field:=56
Else
Range("A5").AutoFilter Field:=56, Criteria1:=Range("BF2").Value
End If
End If
If Target.Address = Range("BF3").Address Then
If Range("BF3") = "All" Then
Range("A5").AutoFilter Field:=54
Else
Range("A3").AutoFilter Field:=54, Criteria1:=Range("BF3").Value
End If
End If
End Sub

When you protect the sheet, there are options to allow the filter. Tick the Autofilter checkbox. You can also set Protection for individual cells. My English translations might be off, but right click the cell(s), select Format Cells(?), then then on the Protection tab, untick "Locked". Refer to this link.

Related

VBA using drop down lists on other worksheets to hide rows automatically

Afternoon all!
I am using the results of various drop down lists to hide the relevant rows on a spreadsheet as the value on the drop down list is changed (so automatically).
With some googling, I have come across the below set up which works nicely, although I have now hit a snag when trying to specify drop down list cell from another worksheet.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim disabled As Boolean
If Range("D2") = "Yes" Then
disabled = True
End If
If disabled Then
Rows("3:8").EntireRow.Hidden = False
Else
Rows("3:8").EntireRow.Hidden = True
End If
End sub
Using the following has not worked, and googling for a solution has lead me up many a dead end:
If Sheets("Topsheet").Range("D27") = "Yes" Then
Am I unable to use values from a neighbouring sheet when declaring a variable due to it being a private sub?
Any help would be much appreciated as I have been stumped on this for a couple of hours!
Your code can be massively simplified. Try using this (You'll have to update the sheet name if it's not the same as yours)
Private Sub Worksheet_Change(ByVal Target As Range)
Sheets("SheetWithRowsToBeHidden").Rows("3:8").EntireRow.Hidden = IIf(Me.Range("D27").Value2 = "Yes", True, False)
End Sub
Also, where have you put this code? Have you put it inside a Module or is it in the Sheet Object? It needs to be in the Sheet Object that has the dropdowns on.

Hide a worksheet based on username

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

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.

Turning off a worksheet change-based event macro in Excel

I've been stuck on this for awhile. I have a macro that runs every time a change is made and creates a data table that updates after each change with information like : Old Value, New Value, Data Changes, etc.
I am trying to kind of pause the worksheet change macro when I don't want it to be run anymore. Ex: If I am plugging in blank information, I don't need to document the fact that it used to be blank, and now it has data, etc.
I made some specifications for if I deleted an entire row as shown here:
If Target.Address = Target.EntireRow.Address Then Exit Sub
but that only dealt with one case. I just now thought of a very simple solution that I will post as the answer, so I hope this will help other people as much as it helped me
It's actually a very simple solution.
To begin pick a cell that has no information in but can be clearly located. For the purpose of this lets say A1.
Now pick key words that you will use to turn the macro on and off. Ex: I just chose True and False (capitals need to be consistent so pick what you want)
At this point, go to the beginning of your worksheet change macro and type in this right after the sub starts:
Private Sub Worksheet_Change(ByVal Target As Range)
If Range("A1").Value = "False" Then
Exit Sub
End If
Now, before your macro starts, it will always verify that the cell doesn't contain False, so if you want it on, put anything else but False, and if you want it off, keep the cell as False. Hope this helps someone.
You want to disable events while ensuring that you enable them later. To do this, use an error handler to catch all errors and set the state back at the end.
Public Sub example()
On Error GoTo errHandler
Application.EnableEvents = False ' => disable events
'The code ...
errHandler:
Application.EnableEvents = True ' => enable events
End Sub

Locking the field in Excel depending on input from another field

I am taking drop-down input in excel field. Depending on this drop-down input, other field need to be locked and change in color.
I have tried writing below VBA but it is not working. Please let me know simple solution.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If (Sheet1.Range("D2").Value = "New") Then
Sheet1.Range("G2").Locked = True
Sheet1.Range("G2").Interior.ColorIndex = 15
Else
Sheet1.Range("G2").Locked = False
Sheet1.Range("G2").Interior.ColorIndex = 36
End If
End Sub
Setting Locked to True or False will have no effect unless the Worksheet is protected. To achieve this your code would also have to temporarily UnProtect and then Protect the Worksheet.
Sheet1.Unprotect
'Lock or unlock cells..
Sheet1.Protect
Note that attempting to do this in the SelectionChange event is not ideal, as this code runs constantly and disables Undo. It is better to use either a Button or, if the drop-down is an ActiveX ComboBox, use its Change event.
You could probably do it with just Conditional Formatting for the colors, but as others have said, Locking a cell means nothing until you Protect the sheet.