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:

  1. 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
  1. 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