How do I avoid run-time error when a worksheet is protected in MS-Excel?
If I understand the question correctly, you will be the one protecting the sheet. If that is the case, you can use the following VBA:
myWorksheet.Protect contents:=True, userinterfaceonly:=True
The key part here is "userinterfaceonly:=true". When a worksheet is protected with this flag set, VBA macros are still allowed to make changes.
Place this code into the WorkBook_Activate
event to automatically protect the workbook and set the flag whenever it is activated.
Edit: Thanks to Lance Roberts for his recommendation to use Workbook_Activate
instead of Workbook_Open
.
Edit: Since the above didn't seem to work, you may have to wrap the failing portion of your VBA code with unprotect/protect commands. If you do that, I would also wrap the entire macro with an error handler, so that the sheet is not left unprotected after an error:
Sub MyMacro
On Error Goto HandleError
...
myWorksheet.unprotect
With ModifyCell.Validation
...
End With
myWorksheet.protect contents:=True, userinterfaceonly:=True
...
Goto SkipErrorHandler
HandleError:
myWorksheet.protect contents:=True, userinterfaceonly:=True
... some code to present the error message to the user
SkipErrorHandler:
End Sub
Edit: Have a look at this thread at PCreview. They went through much the same steps, and came to the same conclusion. At least you're not alone!
I'm not sure if this is a universal solution, but when I've had this error recently, I just had to do a MywkSheet.Activate right before I did the Validation.Add. So:
' set list values based on some conditions not defined for brevitity'
If myCondition then
myNamedRange = "range1"
Else
myNamedRange = "range2"
End If
''--------------------------------------------------
Sheets("mysheet").Activate
''--------------------------------------------------
With modifyCell.Validation
.Delete
'Run time error occurs on the next line'
.Add Type:=xlValidateList, AlertStyle:=xlValidAltertStop, _
Operator:=xlBetween, Formula1:="=" & myNamedRange
...
' skipping more property setting code '
...
End With
in my case, ScreenUpdating was off already, so the user never sees the sheets switching back and forth. HTH.
The problem is that for VBA to be able to edit protected worksheets, the sheet must be protected with the "UserInterfaceOnly" parameter set to True. However, the UserInterfaceOnly parameter is NOT saved when the workbook is saved, so errors will happen if the workbook is closed and reopened.
Here's one solution:
- Create a sub that protects all worksheets and sets the UserInterfaceOnly parameter to true. I split it into ProtectSheet and ProtectAll subs:
_
Sub ProtectSheet(SheetName As String)
Dim pswd As String
pswd = "pass" ' YOU SHOULD GET THE PASSWORD FROM SOMEWHERE SECURE, NOT HARDCODE IT
ThisWorkbook.Worksheets(SheetName).Protect Password:=pswd, DrawingObjects:=True, Contents:=True, Scenarios:=True, _
UserInterfaceOnly:=True, AllowFormattingCells:=False, AllowFormattingColumns:=False, _
AllowFormattingRows:=False, AllowInsertingColumns:=False, AllowInsertingRows:=False, _
AllowInsertingHyperlinks:=False, AllowDeletingColumns:=False, AllowDeletingRows:=False, _
AllowSorting:=False, AllowFiltering:=False, AllowUsingPivotTables:=False
End Sub
Sub ProtectAll()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
ProtectSheet (ws.Name)
Next ws
End Sub
- In ThisWorkbook, protect all the worksheets when the workbook opens:
Private Sub Workbook_Open()
Call ProtectAll ' Protect all with UserInterfaceOnly set to true so VBA can edit
End Sub