I have some VBA code that protects 3 sheets in a single workbook on opening.
Private Sub workbook_open()
Sheets("InputForm").Protect "password", UserInterfaceOnly:=True
Sheets("Invoice").Protect "password", UserInterfaceOnly:=True
Sheets("List").Protect "password", UserInterfaceOnly:=True
End Sub
i also have some code that shows/hides rows based on whether TRUE/FALSE in a cell N14
Private Sub Worksheet_Calculate()
If ActiveSheet.Name = "InputForm" Then
Application.EnableEvents = False
Sheets("Invoice").Rows("57:123").Hidden = Range("N14").Value
Sheets("InputForm").Rows("57:94").Hidden = Range("N14").Value
Application.EnableEvents = True
Else
Application.EnableEvents = False
Application.EnableEvents = True
End If
End Sub
When i use a command button to execute some copy/paste code, i get an Error 1004, unable to set the hidden property of the range class. Debugging points to the Sheets("Invoice")... line.
However, if i end the debugger and click the button again, it seems to work fine...?
Any help would be greatly appreciated
You need to un-protect your sheets before you can make changes to them - even with VBA - it is the same concept.
Related
Very Basic I am sure but I can't figure it out for the life of me.
I have a set of radio buttons that changes the value of cell("L37") between 1 and 2.
I have tried to write the VBA code several different ways without luck. Please advise.
Sub hide_sheet()
If Worksheets("Feedback").Range("L37").Value = 1 Then
Rows("63:93").EntireRow.Hidden = True
Else Worksheets("Feedback").Range("L37").Value = 2 Then
Worksheets("Feedback").Rows("63:93").EntireRow.Hidden = False
End If
End Sub
I had it working perfectly fine via a Macro tied to the radio buttons; however, due to me needing to protect the sheet I needed to change it.
I am using a protect/unprotect VBA code and would like to include it into the code so it won't set off the macro/sheet protected warning.
Here is my protect/unprotect code I am using for everything.
Sub unprotect()
Worksheets("Feedback").unprotect
End Sub
Sub protect()
Worksheets("Feedback").protect , _
AllowFormattingCells:=True, _
AllowFormattingRows:=True
End Sub
Any advice would be greatly appreciated. I Thank You in Advance of your assistance.
Show/Hide Rows
Issues
The Feedback worksheet is not qualified so if the wrong workbook is active, it will fail. To reference the workbook containing this code, you can use ThisWorkbook:
ThisWorkbook.Worksheets("Feedback")...
You are using Rows("63:93") instead of Worksheets("Feedback").Rows("63:93") in the If clause. If the wrong worksheet is active (selected), it will fail.
You are using Else instead of ElseIf.
You can use the With statement to reduce typing as illustrated in the following code.
If you convert the cell value to a string, then if the cell accidentally contains an error value, the code will not fail.
The Code
Sub ShowHideRowsFix()
With ThisWorkbook.Worksheets("Feedback")
.Unprotect
Select Case CStr(.Range("L37").Value)
Case "1"
.Rows("63:93").Hidden = True
Case "2"
.Rows("63:93").Hidden = False
Case Else
End Select
.Protect AllowFormattingCells:=True, AllowFormattingRows:=True
End With
End Sub
An Improvement
To automate this operation (no need for buttons), in the sheet module of the Feedback worksheet identified in the VBE Project explorer window by e.g. Sheet1(FeedBack) (double-click to open), you could use the following code.
Private Sub Worksheet_Change(ByVal Target As Range)
Const CellAddress As String = "L37"
Dim Cell As Range: Set Cell = Me.Range(CellAddress)
If Intersect(Cell, Target) Is Nothing Then Exit Sub
ShowHideRows Cell
End Sub
Sub ShowHideRows(ByVal Cell As Range)
With Cell.Worksheet
.Unprotect
Select Case CStr(Cell.Value)
Case "1"
.Rows("63:93").Hidden = True
Case "2"
.Rows("63:93").Hidden = False
Case Else
End Select
.Protect AllowFormattingCells:=True, AllowFormattingRows:=True
End With
End Sub
I prefer the simplest approach where possible. This is the approach I use to hide columns re-written for your needs.
The following code may exist on the UserForm or in a standard Code Module:
Sub rwControl(ByRef hType As String)
Dim rwVis As Boolean
If hType = "hRW" Then rwVis = True
If hType = "uRW" Then rwVis = False
With ThisWorkbook.Worksheets("Feedback")
.Unprotect
.Rows("63:93").Hidden = rwVis
.Protect
End With
End Sub
You may call this code directly from you RadioButton_Change() Event vy including the following code:
IF RadioButton1.Value = True then 'Assuming the value is 1
rwControl "hRW" 'This hides the Rows
ELSE
rwControl "uRW" 'This unhides the Rows
End If
OR, to keep it really simple:
in your RadioButton_Change() event simply add:
Private Sub RadioButton1 Change()
With ThisWorkBook.Worksheets("Feedback")
.Unprotect
If RadioButton1.Value = True Then
.Rows("63:93").Hidden = True
Else
.Rows("63:93").Hidden = False
End If
.Protect
End With
End Sub
Using this approach negates the need for Worksheet Module Coding and Case Coding and allows you to keep the RadioButtons if you deem them important to the functionality.
I would like to write a code which, before closing the Workbook, sets all the sheets except one cover as very hidden.
I click on the "X" to close the Workbook, the Macro is fired and everything fine.
Then I receive the classic saving form of Excel and, if I click cancel, I receive error 91 - Object variable or With block variable not set.
Could someone explain me why is happening? I used the same code in the past and I did not have this issue
It is interesting because, if there is another excel workbook open at the same time, it works everything fine.
In Tab ThisWorkbook:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.EnableEvents = True
Call my_macro 'defined in a separate module
Application.EnableEvents = False
End Sub
For the sake of clarity in Module 1 the code is following:
Public Sub my_macro()
Application.ScreenUpdating = False
On Error GoTo skip
Dim ws As Worksheet
Sheet8.Visible = True
For Each ws In Worksheets
If ws.Name = "Cover" Then
Else
ws.Visible = xlSheetVeryHidden
End If
Next ws
Sheet8.Select
Range("A1").Select
Application.ScreenUpdating = True
ActiveSheet.EnableSelection = xlNoRestrictions
Application.EnableEvents = True
skip:
Application.EnableEvents = True
End Sub
I have an excel workbook with multiple sheets. Is there any way to password protect users from even opening a sheet within the workbook? The sheet has a large graph on it that I don't want everyone to be able to see, let alone edit.
Thanks in advance for your help
EDIT
I used the following code to allow users to click a formcontrol button to access the sheet in question.
Sub ShowHeatMap()
Dim S As String
S = InputBox("Enter Password")
If S = vbNullString Then
Exit Sub
ElseIf S <> "wiretransfer" Then
Exit Sub
Else
Worksheets("Training Heat Map").Visible = xlSheetVisible
End If
End Sub
This is associated with my button on a kind of "homepage" sheet that I added to the workbook.
But I can't get the sheet to remain hidden when you open the workbook again. I tried this code:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Worksheets("Training Heat Map").Visible = xlSheetVeryHidden
End Sub
Any ideas? This code is inputted on the module for the sheet under general declarations
Via this answer, I think this might do the trick for you. Within VBA, put this within ThisWorkbook:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim MySheets As String, Response As String
MySheet = "Sheet1"
If ActiveSheet.Name = MySheet Then
ActiveSheet.Visible = False
Response = InputBox("Enter password to view sheet")
If Response = "MyPass" Then
Sheets(MySheet).Visible = True
Application.EnableEvents = False
Sheets(MySheet).Select
Application.EnableEvents = True
End If
End If
Sheets(MySheet).Visible = True
End Sub
Obviously will require a bit of tailoring to your needs. Remember that you will also need to password protect your VBA code, otherwise anyone will be able to view it and find out the password.
I want to disable cell editing (direct typing into cell) but want to update that cell through code without protecting worksheet
Does anyone have any idea?
In the worksheet's code module:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Range("A1:A10"), Target) Is Nothing Then
Application.EnableEvents = False
Target.ClearContents '// Assuming you want to keep it blank
Application.EnableEvents = True
End If
End Sub
Then in your code whenever you want to change a value, just disable events before hand:
'// Will be deleted
Range("A5").Value = "TEST"
'// Will not be deleted
Application.EnableEvents = False
Range("A5").Value = "TEST AGAIN"
Application.EnableEvents = True
I had a similar issue and found a workaround. For whatever reason I couldn't get my macros to run correctly with the sheets protected so what I did is as a code to Pop up a message box for any cells that I didn't want the user to change. Then I added "Application.DisplayAlerts = False" to the beginning of any codes that needed to modify those cells and reset the alerts back to True at the end of those codes.
I'm curious as to whether it's possible to pass the protection status of an excel worksheet to a cell of that worksheet.
e.g.
Sheet1 is locked for editing...cell A1 would be programmed to say "locked"
Sheet1 is unlocked...cell A1 would say "unlocked".
A button on the sheet would be used to toggle worksheet protection on and off.
My sheet will be locked upon opening using a workbook_open event.
This is for a sheet where I don't want the formulae getting all mucked up upon use, but where full access might be required. Its more as a reminder to the user that they are in "Unlocked" Mode so to be extra careful.
Is using VBA a foregone conclusion?
I'm a VBA noob but don't mind using code as a solution for this
Any thoughts or suggestions welcome
You could use code in an ActiveX button on Sheet1 to do this simply
Const strPAss = "test"
Private Sub CommandButton1_Click()
If ActiveSheet.ProtectContents Then
ActiveSheet.Unprotect strPAss
[a1].Value = "unlocked"
Else
[a1].Value = "locked"
ActiveSheet.Protect strPAss
End If
End Sub
Put this in the worksheet's code module, which will place a reminder in the Status Bar (this avoids needing to lock/unlock the sheet in order to write the status in to cell A1).
Put this in Sheet1 code module. The macro will execute every time sheet1 is activated.
Private Sub Worksheet_Activate()
If ActiveSheet.ProtectContents then
Application.StatusBar = "This sheet is protected"
Else:
Application.StatusBar = "This sheet is unprotected"
End If
End Sub
Private Sub Worksheet_Deactivate()
Application.StatusBar = False
End Sub
To protect/unprotect the worksheet you could add this to an Insert>Module. Then attach these macros to separate command buttons, or run from the Developer>Macros ribbon.
Const myPassword as String = "password" '<-- replace "password" with your password
Sub Sht1Protect()
Sheet1.Protect myPassword
End Sub
Sub Sht1Unprotect()
Sheet1.Unprotect myPassword
End Sub
To ensure the sheet is always protected when you close the file, insert this in the Workbook code module
Private Sub Workbook_Close()
Sht1Protect
End Sub
You may need additional handling to control whether the file is saved/not saved etc.