根据我需要的特定单元格的值,可能会取消保护工作表,将范围设置为锁定并重新保护工作表。相反,如果单元格的值(在这种情况下单元格B4等于" work")那么我需要取消保护工作表,解锁单元格,然后重新保护工作表。这样做的原因是,当单元格B4不等于工作时,我想要停止用户标签到单元格A8:B19。当B4 ="工作"用户可以将数字输入到单元格A8:B19中。当B4<>时,输入的选项有限。 "工作"并且我的设置只在选中的未锁定单元格之间进行选项卡,这使输入更容易。
目前我有这个:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("B4")) Is Nothing Then
If Range("B4").Value = "work" Then
Shapes("Rectangle 1").Visible = False
Application.EnableEvents = False
ActiveSheet.Unprotect
ActiveSheet.Range("A8:B19").Locked = True
ActiveSheet.Protect ‘When the code hits this line it throws error 400
Application.EnableEvents = True
End If
If Range("B4").Value <> "work" Then
Shapes("Rectangle 1").Visible = True
Application.EnableEvents = False
ActiveSheet.Unprotect
ActiveSheet.Range("A8:B19").Locked = True
ActiveSheet.Protect ‘When the code hits this line it throws error 400
Application.EnableEvents = True
End If
End If
End Sub
显然,它取决于单元格B4的值,以及哪些&#34; ActiveSheet.Protect&#34;导致错误发生,但它总是这样。注释掉违规行允许VBA代码按预期运行,但它会使工作表解锁。我试过移动&#34; ActiveSheet.Protect&#34;进一步向下划线,在不同的子区域调用它并且没有运气,它总是导致错误400.我意识到Elseif无疑会更好地练习但是我从If,ElseIf End改变如果看看是否它有所不同。它没有。
奇怪的是,我尝试用类似的东西在另一张Excel工作表中用以下代码证明原理:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A1")) Is Nothing Then
Dim i As Integer
If Cells(1, 1) = "unlock" Then
i = 1
Shapes("Oval 1").Visible = False
Application.EnableEvents = False
ActiveSheet.Unprotect
For i = 1 To 5
Cells(i, 2) = i
Next i
ActiveSheet.Range("C1:C5").Locked = False
ActiveSheet.Protect
ElseIf Cells(1, 1) <> "unlock" Then
i = 1
Shapes("Oval 1").Visible = True
Application.EnableEvents = False
ActiveSheet.Unprotect
For i = 1 To 5
Cells(i, 2) = ""
Cells(i, 3) = ""
Next i
ActiveSheet.Range("C1:C5").Locked = True
ActiveSheet.Protect
End If
Application.EnableEvents = True
End If
End Sub
这完全符合我的预期,并且做了类似的事情。除了不同的单元格和for循环之外,我无法看到上面两个代码示例之间关于unprotect,更改锁定变量,保护进程的任何差异。
感到困惑,任何帮助都非常感激。
答案 0 :(得分:1)
使用UserInterfaceOnly
参数 - 这可以保护工作表,但仍允许进行任何编程更改,而无需取消保护和重新保护:
Sheets("Some Sheet").Protect Password:="Pass123", UserInterfaceOnly:=True
Sheets("Some Sheet").Range("A1").Value = "Foo" '// code runs without error
您可以使用Workbook_Open
事件确保以这种方式锁定所有必需的工作表,然后无需在任何其他代码中对其进行管理:
Private Sub Workbook_Open()
For Each ws In ThisWorkbook.Sheets
ws.Protect UserInterfaceOnly:=True
Next
End Sub