我是excel VBA的新手,我无法在任何地方找到答案。在我的工作表“跟踪日志”中,我希望A1:A70
范围内没有文本的单元格允许用户编辑(然后在更改后自动锁定),而带文本的单元格始终受密码保护。我还希望范围使用与工作表不同的密码,并且用户可以随时输入密码,以便编辑范围内包含文本的单元格。
我希望将相同的代码应用于范围B1:B70
,K1:K70
,但每个范围使用不同的密码,所有这些密码都与工作表不同。总的来说,我打算为这张单页提供4个密码。
当前代码我在输入文本后使用锁定单元格,但它正在更改工作表密码而不仅仅是单元格,而您只输入一次密码。这有意义吗?这是我正在使用的代码:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim blnUnlockedAllCells As Boolean
Const RangeToLock As String = "A2:A70" '<< adjust to suit
If Target.Cells.Count > 1 Then Exit Sub
If Not blnUnlockedAllCells Then
Me.Cells.Locked = False
On Error Resume Next
Me.Range(CStr(RangeToLock)).SpecialCells(2).Locked = True
On Error GoTo 0
blnUnlockedAllCells = True
Me.Protect Password:="pwd", userinterfaceonly:=True
End If
If Not Application.Intersect(Target, Me.Range(CStr(RangeToLock))) Is Nothing Then
If Len(Target) Then Target.Locked = True
End If
答案 0 :(得分:1)
你不需要锁定它们。我刚录制了这个宏来弄清楚如何为多个范围做这个:
With ActiveSheet
.Protection.AllowEditRanges.Add Title:="Range1", Range:=.Range("G8:J10"), Password:="qq"
.Protection.AllowEditRanges.Add Title:="Range2", Range:=.Range("K11:L12"), Password:="aa"
End With
但请记住,如果此人知道如何打开代码窗口,他们将很容易看到您的密码。
答案 1 :(得分:0)
代码“setupranges”可以设置要编辑的范围和密码。这完成了所有的工作。将以下两个子例程复制并粘贴到新模块中(插入模块)。确保将密码更改为您已设置的密码。
Sub setupranges(wsname As String, rangeX As String)
Dim rangea, rangeb, rangek As String
Dim pwda, pwdb, pwdk As String
Dim Ws As Worksheet
Dim pwdws As String
Set Ws = Worksheets(wsname)
rangea = "A1:A70"
rangeb = "B1:B70"
rangek = "K1:K70"
pwda = "aaa"
pwdb = "bbb"
pwdk = "kkk"
pwdws = "pwd"
On Error Resume Next
Ws.Unprotect Password:=pwdws
On Error GoTo 0
Select Case rangeX
Case Is = "all"
Call deleterangeifexists(Ws, "a")
Ws.Protection.AllowEditRanges.Add Title:="arange",Range:=Ws.Range(rangea), Password:=pwda
Call deleterangeifexists(Ws, "b")
Ws.Protection.AllowEditRanges.Add Title:="brange", Range:=Ws.Range(rangeb), Password:=pwdb
Call deleterangeifexists(Ws, "k")
Ws.Protection.AllowEditRanges.Add Title:="krange", Range:=Ws.Range(rangek), Password:=pwdk
Case Is = "a"
Call deleterangeifexists(Ws, "arange")
Ws.Protection.AllowEditRanges.Add Title:="arange", Range:=Ws.Range(rangea), Password:=pwda
Case Is = "b"
Call deleterangeifexists(Ws, "brange")
Ws.Protection.AllowEditRanges.Add Title:="brange",Range:=Ws.Range(rangeb), Password:=pwdb
Case Is = "k"
Call deleterangeifexists(Ws, "krange")
Ws.Protection.AllowEditRanges.Add Title:="krange", Range:=Ws.Range(rangek), Password:=pwdk
End Select
Ws.Protect Password:=pwdws, userinterfaceonly:=True
End Sub
如果在尝试添加范围时已经存在该范围,则会出现错误,因此如果已存在,则会删除已定义的范围。
Sub deleterangeifexists(Ws As Worksheet, Title As String)
Dim rangetocheck As AllowEditRange
For Each rangetocheck In Ws.Protection.AllowEditRanges
If rangetocheck.Title = Title Then
rangetocheck.Delete
Exit Sub
End If
Next
End Sub
然后您必须从工作表中调用setupranges,例如 调用setupranges(“sheet1”,“all”) 将重置所有范围的所有密码 call setupranges(“sheet1”,“arange”) 将仅重置A列范围的密码。
我建议使用worksheet_change或worksheet_selectionchange,具体取决于您希望工作簿的行为方式。 使用Worksheet_change时请记住,您的用户可能会解锁一个范围,然后不要更改任何内容,这样您的例程就不会运行,并且范围将保持解锁状态。使用Worksheet_selectionchange,代码将随着细胞焦点的每次更改而运行,这可能会很慢。其中一个给你作为Target你现在所在的细胞,一个给你你来自的细胞,这可能会让你更容易或更难。
无论哪种方式,您的工作表代码都将具有: 如果condition为true(无论你想测量什么条件)那么 调用setupranges(“sheet1”,“all”) 结束如果