Allowing user to hide columns when sheet is locked - excel

I am using the following VBA script to provide users certain permissions when a sheet in a workbook is locked. I cannot figure out how to add a line that would also allow the user to hide and unhide columns. Any suggestions?
Sub EnableOutlining()
'Update 20140603
Dim xWs As Worksheet
Set xWs = Application.ActiveSheet
Dim xPws As String
xPws = Application.InputBox("Password:", xTitleId, "", Type:=2)
xWs.Protect Password:=xPws, Userinterfaceonly:=True
xWs.EnableOutlining = True
xWs.EnableOutlining = True
xWs.EnableAutoFilter = True
xWs.EnableFormatConditionsCalculation = True
End Sub

Going to work on a way to check that last user action was in fact hide / unhide and nothing else. But for now should allow user to hide / unhide.
For columns:
xWs.protect Password:= "1234",AllowFormattingColumns:= true
For rows:
xWs.protect Password:= "1234",AllowFormattingRows:= true
This script should help limit user activity to only adjusting column widths. (lastAction describes hiding columns as adjust width, must be that hiding columns is really just a function that minimizes column width, not some special action)
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim lastAction As String
lastAction = Application.CommandBars("Standard").Controls("&Undo").List(1)
If lastAction <> "Column Width" Then
Application.EnableEvents = False
Application.Undo
MsgBox "PLEASE ONLY HIDE OR UNHIDE COLUMNS"
Application.EnableEvents = True
End If
End Sub

To do this you just need to change the sections your allowing users to work on when locking the sheet. I selected everything but "select locked cells" and it would then work. This meant the code was still hidden in cells I didn't want to be edited but the hide expand button based on my VBA code was working.

Related

Excel using auto-generated hyperlinks to hide rows in a table

I have a table where I want to be able to hide individual rows at a mouse click. The (seemingly) easiest solution I've found is to have a column filled with hyperlinks that call a macro to hide the row that they're in.
There are two ways of calling macros from hyperlinks: using Worksheet_FollowHyperlink with manual hyperlinks, and using =HYPERLINK.
The former works fine, except there's no way (that I've found) to have them generate automatically when new rows are added to the table. I would have to either manually copy them down every time, which is unviable, or add them with VBA, which adds a bunch of complexity to an otherwise simple task.
The latter generates fine, being a formula, but it doesn't actually work. It doesn't trigger Worksheet_FollowHyperlink, and when using =HYPERLINK("#MyFunction()") it just doesn't hide rows (or do much other than editing cells contents).
Function MyFunction()
Set MyFunction = Selection
Selection.EntireRow.Hidden = True
End Function
Is there a good solution to this?
Rather than a Hyperlink, you could handle a Double Click event on the table column
Something like
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim NameOfTableColumn As String
On Error GoTo EH:
NameOfTableColumn = "DblClickToHide" ' update to suit your table
If Not Application.Intersect(Target, Target.ListObject.ListColumns(NameOfTableColumn).DataBodyRange) Is Nothing Then
Target.EntireRow.Hidden = True
Cancel = True
End If
Exit Sub
EH:
End Sub
Please, copy the next code in the sheet code module where the table to be clicked exists. Clicking on each cell in its first column (dynamic to rows adding/insertions/deletions), the clicked row will be hidden:
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim tbl As ListObject
If Target.cells.CountLarge > 1 Then Exit Sub
Set tbl = Me.ListObjects(1) 'you may use here the table name
If Not Intersect(Target, tbl.DataBodyRange.Columns(1)) Is Nothing Then
Application.EnableEvents = False
Target.EntireRow.Hidden = True
Application.EnableEvents = True
End If
End Sub
It would be good to think about a way to unhide the hidden row if/when necessary. If only a row should be hidden at a time, it is easy to unhide all the rest of column cells...

Unhide/Hide rows in excel with a form checkbox

I have a form created in excel which has rows [10:48] hidden and I want to make so that when you click a checkbox rows [10:48] are unhidden. I assigned a macro to the checkbox and using this formula:
Private Sub CheckBox45_Click()
If CheckBox45 = True Then
[10:48].EntireRow.Hidden = False
Else: [10:48].EntireRow.Hidden = True
End If
End Sub
When I click the checkbox nothing happen, but when I unhide the rows and click the checkbox it hides the rows. Which makes me think that only one of the actions is working. Is there a way to fix this?
Thanks in advance for the help.
Don't know if this matters but the form checkbox is in column D row 6
This assumes you are hiding/unhiding rows on Sheet 1 and the checkbox belongs to sheet 1 of the workbook, then:
Private Sub CheckBox30_Click()
If ThisWorkbook.Sheets(1).CheckBoxes("Check Box 30").Value = 1 Then
ThisWorkbook.Sheets(1).Rows("10:48").Hidden = true
Else
ThisWorkbook.Sheets(1).Rows("10:48").Hidden = false
End If
End Sub
Here is another approach.
The statement ws.CheckBoxes("Check Box 30") = 1 will either return TRUE or FALSE which will either hide, or unhide, your target rows.
Private Sub CheckBox30_Click()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
ws.Range("A10:A48").EntireRow.Hidden = ws.CheckBoxes("Check Box 30") = 1
End Sub

Lock in dropdown selection

I'm creating a quiz.
Questions on one worksheet and the answers on another.
When a question is answered another field with this formula
=IF(C5="","",IF(C5=Answers!A5,"Correct","Incorrect"))
tells the person if the answer is correct or incorrect.
I am using data validation with dropdown lists so they can only choose true/false, (a, b, c, d) etc.
Is there a way to lock in a selected answer, until a master reset button is pressed?
For example,
Question is in A1
The possible answers are in the form of a dropdown menu in B1.
Sometimes the answer is in the form of a true false, sometime it is in the form of a multiple choice. In the example of true false, if the person puts in true, c3 will say correct or if they put false, then incorrect.
As it is now, the person can switch back and forth as much as they want.
I am looking to make it so once an answer is selected, they cannot change it.
You can use Sheet Protection, combined with Range Locking and a Change event.
Put this code in the relevant Worksheet Module. Adjust the Private constants to suit your needs.
Option Explicit
' Reference the cells that your users may enter data into
Private Const DataCells As String = "J1,J3,J5"
Private Const PW As String = "password"
Private Sub Worksheet_Change(ByVal Target As Range)
Dim cl As Range
Dim DataRange As Range
Set DataRange = Me.Range(DataCells)
'Loop thru changed cells
For Each cl In Target.Cells
'If changed cell is in the DataCells range and is not blank, lock it
If Not Application.Intersect(cl, DataRange) Is Nothing Then
If Not IsEmpty(cl) Then
Me.Unprotect PW
Target.Locked = True
Me.Protect PW
End If
End If
Next
End Sub
'Re-enable data entry to all DataCells
Sub MasterReset()
'Unlock the sheet, prompt for password
Me.Unprotect
'Unlock the cells
Me.Range(DataCells).Locked = False
'Optional, clear DataCells
Me.Range(DataCells).ClearContents
'Lock the sheet again
Me.Protect PW
End Sub
This works pretty good:
In the "This Workbook" module, insert the code:
Private Sub Workbook_Open()
Sheet1.Protect userinterfaceonly:=True 'allows macros to run
Sheet1.Range("A1:A20").Locked = False 'replace this range with the range the user deals with.
End Sub
In the sheet module that the user will be interacting with, add this code:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Locked = True Then Exit Sub
If Target.Locked = False Then
If Target.Value = "" Then Exit Sub
If Target.Value <> "" Then Target.Locked = True
End If
End Sub
That should take care of things for you!

VBA code to hide/unhide multiple rows in another worksheet based on cell output from another worksheet

I want to use VBA code for the following: based on a cell output (either "TRUE" or "FALSE" in cell W20, which changes based on whether a user checks a box or not), I want rows to be hidden/unhidden on another worksheet called "Analysis" worksheet based on the code below. I right clicked the "Summary" tab where cell W20 and the checkbox are located -> view code -> wrote the code below, but it's not working. I am very new to VBA, please help, it would be very appreciated, thanks in advance
Sub Worksheet_Change(ByVal Target As Range)
Set Target = Range("$W$20")
If Target.Value = "FALSE" Then
Sheets("Analysis").Rows("54:55").EntireRow.Hidden = True
Else
Sheets("Analysis").Rows("54:55").EntireRow.Hidden = False
End If
If Target.Value = "FALSE" Then
Sheets("Analysis").Rows("94:95").EntireRow.Hidden = True
Else
Sheets("Analysis").Rows("94:95").EntireRow.Hidden = False
End If
If Target.Value = "FALSE" Then
Sheets("Analysis").Rows("134:135").EntireRow.Hidden = True
Else
Sheets("Analysis").Rows("134:135").EntireRow.Hidden = False
End If
End If
End Sub
Excel doesn't recognize the modification of a cell value caused by the manipulation of form controls. I assume this is because Excel links a form control to a value and applies the changes itself, therefore not considering it a user change in the spreadsheet.
In order to make your code work, you will have to move your code into a module as a click event of your form control. Click the Developer tab and then Visual Basic. Once Visual Basic is open, you will notice on the left pane that you have a list of your worksheets within a VBA Project bearing the name of your workbook and your macro is currently within one of them. Once you found it, delete the code of your macro. Then, right-click on the name of your workbook and then select Insert > Module...
On the coding pane, insert this modified code:
Sub NameOfYourFormControlCheckBox_Click()
Dim MyRange As Range
Set MyRange = Range("$W$20")
If MyRange = False Then
Sheets("Analysis").Rows("54:55").EntireRow.Hidden = True
ElseIf MyRange = True Then
Sheets("Analysis").Rows("54:55").EntireRow.Hidden = False
End If
End Sub
Make sure that the name of the sub is the name of your form control (checkbox) followed by an underscore and then "click".
Hope this helps!

How to set password when someone clicks on unprotectsheet in excel and create a button for editing

I have locked cells in a spreadsheet using this lines of code.
Range("A1:D23").Select
Selection.Locked = True
ActiveSheet.Protect Contents:=True
This prompts me whenever I click on a cell which is readonly to unprotect sheet from review tab and might be prompted for password.
My problem is, it is not prompting for password.How do I first set password when he wants to unprotect.Secondly I want to pass the row information that he selected to change and want to create a button when the adjoining readonly cell is used for editing.
I get the first part of your question. You need to specify a password argument as part of the worksheet's Protect method:
Sub lockSheet()
With ActiveSheet
'Check sheet is not already protected
If Not .ProtectContents Then
'Clear any existing lock settings
.Cells.Locked = False
.Range("A1:D23").Locked = True
.Protect Contents:=True, Password:="pw"
End If
End With
End Sub
Note that it is not necessary to select a range before modifying it, simply apply the action directly to the range.
The password is obviously visible in plaintext, if you need to secure to any degree then you'll also need to apply a password to the VBA project.
To address the second part of your question, as amended in your comment:
Private Sub Worksheet_SelectionChange(ByVal target As Range)
If target.Locked Then
With ActiveSheet
.Unprotect
If Not .ProtectContents Then
target.Locked = False
.Protect Contents:=True, Password:="pw"
End If
End With
End If
End Sub
This would need added to the worksheet module.

Resources