使用与工作表不同的密码在文本输入后锁定单元格范围

时间:2017-11-07 20:17:42

标签: excel vba excel-vba

我是excel VBA的新手,我无法在任何地方找到答案。在我的工作表“跟踪日志”中,我希望A1:A70范围内没有文本的单元格允许用户编辑(然后在更改后自动锁定),而带文本的单元格始终受密码保护。我还希望范围使用与工作表不同的密码,并且用户可以随时输入密码,以便编辑范围内包含文本的单元格。

我希望将相同的代码应用于范围B1:B70K1: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

2 个答案:

答案 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”)     结束如果