2017-08-10 106 views
0

以下是方案。我想要一个命令按钮,只有当一行中的特定单元格非空时才会出现。我也喜欢命令按钮来锁定整个行一旦点击(通过“锁定”,我的意思是防止单元格编辑)。仅当选定行中的单元格非空白时出现的VBA代码

我所遇到以下两个代码:隐蔽

1.工作表的代码/取消隐藏按钮:

Private Sub Worksheet_Change(ByVal Target As Range) 

    If Cells(1, 14).Value <> "" Then 
     CommandButton2.Visible = True 
    Else 
     CommandButton2.Visible = False 
    End If 
End Sub 

Private Sub Worksheet_SelectionChange(ByVal Target As Range) 
End Sub 

2.模块代码用于使按钮在锁定单元单击该按钮:

Sub CommandButton1_Click() 
    ActiveCell.EntireRow.Locked = True 
    ActiveCell.EntireRow.FormulaHidden = False 
    ActiveSheet.Protect Password:="password", DrawingObjects:=True, Contents:=True, Scenarios:=True 
    ActiveSheet.EnableSelection = xlUnlockedCells 
End Sub 

但是,挑战在于我希望按钮适用于每一行,锁定仅适用于D1到N1。但是,每列的按钮可能会变得杂乱,并减慢电子表格的性能。那么,有没有一种方法可以使用一个按钮(PS我可以将按钮放在电子表格的顶部,我可以冻结最上面的一行,以便始终显示按钮,而不管我在电子表格)?我想如果我正在第5行,本身,我可以选择第5行(通过单击行标题,然后代码可以评估N5,然后命令按钮出现,如果N5不是-blank,然后点击按钮时,单元格D5到N5被锁定,其他所有行都是同样的东西

+0

单元格如何变为非空白? – jsotola

+0

@jsotola。你好,伙计。通过向其输入数据,单元格变为非空白。我想锁定他们点击按钮后输入的数据。 – Omar

+0

提示:您可以用一行代替工作表中的'if ... then ... else' CommandButton2.Visible =(Cells(1,14).Value <>“”)' – jsotola

回答

1

请尝试下面的代码将它安装在您想要的工作表的代码表中你的按钮

查看顶部的Enum作为某种控制面板,这是你在整个代码中设置参数的地方,例如,你可以将第一个数据行从2更改为其他东西。命名为D列“NclTest”和列N“NclResult ”。使用编辑/替换将这些名称更改为更合适的名称。请注意,枚举名称不区分大小写。所以,如果你用小写字母写下他们,我的宝贵资本将永远消失。

我已经设置了列O(15)采取“按钮”。如果您在列O中有其他内容,则必须更改。分配一个空列。

现在,当您激活工作表时,将会检查列N中的所有项目,并在列O中创建“按钮”。每当有更改时,都会进行更新。因此不需要超过一次。但请记住,更新不适用于多个单元格。因此,如果您复制/粘贴更大的范围,请停用并重新激活工作表以更新按钮。

Option Explicit 

    Const Pw As String = "password" 

Private Enum Ncl    ' worksheet columns 
    ' 11 Aug 2017 
    NclFirstDataRow = 2   ' change as appropriate 
    NclTest = 4     ' 4 = D (used to test if range is locked) 
    NclResult = 14    ' 14 = N 
    NclButton = 15    ' = column O (change as required) 
End Enum 

Private Sub Worksheet_Activate() 
    ' 29 Aug 2017 

    Dim TestVal 
    Dim Cap As String 
    Dim Rl As Long 
    Dim R As Long 

    Application.ScreenUpdating = False 
    With ActiveSheet 
     Rl = .Cells(.Rows.Count, NclResult).End(xlUp).Row 
     For R = NclFirstDataRow To Rl 
      ResetButton R 
     Next R 

     ' you can double-click this cell to end Administrator rights 
     .Cells(1, NclButton).Locked = False 

     .Protect Password:="", _ 
       DrawingObjects:=True, _ 
       Contents:=True, _ 
       Scenarios:=True, _ 
       UserInterfaceOnly:=True 
     .EnableSelection = xlUnlockedCells 
    End With 
    Application.ScreenUpdating = True 
End Sub 

Private Sub Worksheet_Change(ByVal Target As Range) 
    ' 29 Aug 2017 

    Dim LockStatus As Boolean 

    Set Target = Target.Cells(1)  ' only accept first cell 
             ' meaning you can't copy/paste ranges 

    If Not Application.Intersect(Target, WsRange) Is Nothing Then 
     If Target.Locked Then 
      MsgBox "This cell is locked for editing", _ 
        vbInformation, "Modification not allowed" 

      With Application 
       .EnableEvents = False 
       .Undo 
       .EnableEvents = True 
      End With 
      Exit Sub 
     End If 
    End If 

    ' reset the button when Result is changed 
    If Application.Intersect(Target, WsRange(C:=NclResult)) Is Nothing Then 
     ' reset range lock when button is changed 
     If Not Application.Intersect(Target, WsRange(C:=NclButton)) Is Nothing Then 
      With Target 
       If Len(Trim(.Value)) Then 
        LockStatus = (.Value = BtnCap(1)) 
        WsRange(.Row).Locked = LockStatus 
       Else 
        ResetButton .Row 
       End If 
      End With 
     End If 
    Else 
     ResetButton Target.Row 
    End If 
End Sub 

Private Sub Worksheet_SelectionChange(ByVal Target As Range) 
    ' 29 Aug 2017 

    Static PermitEdit As Boolean 
    Dim Cap As String 

    Set Target = Target.Cells(1)  ' only accept first cell 
             ' meaning you can't copy/paste ranges 
    If Target.Address = ActiveSheet.Cells(1, NclButton).Address Then 
     If PermitEdit Then 
      PermitEdit = False 
      MsgBox "Administrator rights have been terminated.", _ 
        vbInformation, "End of Admin session" 
     End If 
    Else 
     If Not Intersect(Target, WsRange(C:=NclButton)) Is Nothing Then 
      Application.EnableEvents = False 
      With Target 
       Do While Not PermitEdit 
        If RefuseAccess(PermitEdit) Then GoTo AccessDenied 
       Loop 
       Cap = Trim(.Value) 
       If Len(Cap) Then 
        .Value = BtnCap(Int(Cap = BtnCap(1)) + 1) 
       End If 
       .Offset(0, -1).Select 
      End With 
AccessDenied: 
      Application.EnableEvents = True 
     End If 
    End If 
End Sub 

Private Function RefuseAccess(PermitEdit As Boolean) As Boolean 
    ' 29 Aug 2017 

    Dim Pass As String 
    Dim Rl As Long 

    Pass = InputBox("Please enter the administrator's password", _ 
        "Password required") 
    PermitEdit = Not CBool(StrComp(Pass, Pw, vbBinaryCompare)) 
    If PermitEdit Then 
     With ActiveSheet 
      Rl = .Cells(.Rows.Count, NclResult).End(xlUp).Row 
      .Range(.Cells(NclFirstDataRow, NclButton - 1), .Cells(Rl, NclButton)).Locked = False 
     End With 
    Else 
     If Len(Pass) Then 
      MsgBox "The password is not correct." & vbCr & _ 
        "Access will be denied.", _ 
        vbInformation, "Invalid password" 
     End If 
    End If 
    RefuseAccess = Not PermitEdit 
End Function 

Private Function BtnCap(ByVal CapId As Long) As String 
    ' 11 Aug 2017 
    BtnCap = Split("LOCK,UNLOCK", ",")(CapId) 
End Function 

Private Function WsRange(Optional R As Long, _ 
         Optional C As Long) As Range 
    ' 11 Aug 2017 

    Dim Rstart As Long, Rend As Long 
    Dim Cstart As Long, Cend As Long 

    If R Then 
     Rstart = R 
     Rend = R 
    Else 
     Rstart = NclFirstDataRow 
     Rend = Cells(Rows.Count, NclResult).End(xlUp).Row 
    End If 

    If C Then 
     Cstart = C 
     Cend = C 
    Else 
     Cstart = NclTest 
     Cend = NclResult 
    End If 

    Set WsRange = Range(Cells(Rstart, Cstart), Cells(Rend, Cend)) 
End Function 

Private Sub ResetButton(ByVal R As Long) 
    ' 11 Aug 2017 

    Dim TestVal 
    Dim Cap As String 

    With Cells(R, NclResult) 
     TestVal = .Value 
     If Len(TestVal) Then 
      Cap = "" 
     Else 
      ' if NclTest is locked then D:N are presumed locked 
      Cap = BtnCap(Int(Cells(R, NclTest).Locked) + 1) 
     End If 
    End With 

    With Cells(R, NclButton) 
     If .Value <> Cap Then 
      .Value = Cap 
     End If 
    End With 
End Sub 

没有按钮。这只是列O中标有“LOCK”或“UNLOCK”的单元格。虽然列N不是空列O将是空白的。如果N为空,O将会有一个按钮,它可以点击。您不能点击两次而不点击其他地方。这是Excel,而不是我。您可以按Delete按照您希望的频率切换。

当“按钮”显示“锁定”时,单元格D:N将被解锁并可以进行编辑。如果编辑N,该按钮可能会消失。如果按钮是“UNLOCK”,则单元格被锁定,当您尝试编辑它们之后编辑被反转时,您会收到一条消息。你猜对了:我不喜欢工作表保护。

使用代码或者只是格式化O列,可以轻松地对“按钮”进行一点格式化。使用类似的方法,您可以突出显示锁定的单元格。我不想这样做。所以我把最好的一部分乐趣留给了你。 :-)

+0

嗨。我很抱歉迟到的回复。在您发布上述答案的第一天,我看到了您的消息,但当天我无法在调试过程中使其正常工作,然后由于我们需要将电子表格放在网上,因此我们都可以合着者。我确定在输入代码时我一定输入了错误。我会尽快再检查一次。再次感谢!! – Omar

+0

谢谢您的礼遇。我在我的电脑上测试了这些代码。所以我很自信它也适合你。让我知道,如果我能帮忙。 – Variatus

+0

再次感谢您的辛勤工作。你对该代码所做的是令人兴奋的。恐怕我不是很清楚。我只想为管理员保留解锁选项。我正在设置这个以防止更改。或者有没有一种方法可以在没有按钮的情况下完成此任务,例如当用户保存工作簿时,他在该会话中输入的所有内容都被锁定。但诀窍是我需要一个有权访问解锁并进行更改的管理员 – Omar

相关问题