【问题标题】:How to Lock Cell based on the value of the another cell and perform data validation如何根据另一个单元格的值锁定单元格并执行数据验证
【发布时间】:2016-07-01 10:11:21
【问题描述】:

我对 VBA 代码非常陌生。现在,我被分配执行一项任务,以验证 Excel 工作表中的数据。

例如,在我的 A 列 中,我有一个下拉菜单,允许用户仅在“是”或“否”之间进行选择。

  • 如果用户选择“是”,则 B 列和 C 列中的单元格将被标记为必填项且不能为空。我想对此添加验证错误。

    **Example 1: If A1 and A30 == YES**
    
    • B1 和 C1,B30 和 C30 是强制性的

    • 将为必填单元格填充颜色,并在单元格已有值时移除填充颜色

    • 当这些单元格为空白且超出时引发验证错误 所需的字符数。

      示例 2:如果 A99 == NO

    • B99 将被锁定,不允许用户输入数据 在这个单元格上。可能我们可以将单元格值添加为“NA”以避免 混乱

我能够使用数据验证和条件格式来捕捉这一点。但是,我无法执行锁定功能,因为根据研究,我需要一个 VBA 代码。

【问题讨论】:

  • 我认为您可以通过验证中的逻辑来做到这一点...
  • 你可能会发现这个question helpful。 TL;DR:ActiveSheet.Protect 将锁定工作表。 Range("A1:D5").Locked = False 设置锁的异常。最后ActiveSheet.Unprotect 恢复读/写访问权限。

标签: vba excel excel-formula


【解决方案1】:

这样的事情应该可以工作。

将其放入要应用到的工作表的代码模块中。

Private Sub worksheet_change(ByVal target As Range)

    ''''' CHECK IF THE CHANGED CELL IS IN RANGE A1:A99 (OR ANY OTHER RANGE YOU DEFINE)
    If Not Intersect(target, Range("A1:A99")) Is Nothing Then

        ''''' UNPROTECT THE SHEET
        ActiveSheet.Unprotect

        ''''' IF THE CELL CHANGED IS NOW 'YES'
        If target = "Yes" Then

            ''''' WE DEFINE HOW MANY COLUMNS TO MOVE ACROSS FROM THE CELL THAT CHANGED AND DO THE ACTIONS IN THE CODE BELOW
            ''''' SO IN THIS EXAMPLE WE'RE MOVING ACROSS 1 CELL TO B1 AND THEN 2 CELLS TO C1
            ''''' SO TO GET TO AA1 AND AB2 WE'D DO i = 26 to 27
            ''''' IF WE WANTED TO ACCESS AA1 ALL THE WAY THROUGH TO AZ1 WE'D DO i = 26 to 51
            For i = 1 To 2

                ''''' MOVE ACROSS i NUMBER OF CELLS FROM THE CELL THAT CHANGED
                With target.Offset(0, i)

                    ''''' UNLOCK THE CELL
                    .Locked = False

                    '''''SET THE CONDITIONAL FORMATTING
                    .FormatConditions.Add Type:=xlExpression, Formula1:="=ISBLANK(" & target.Offset(0, i).Address & ")"
                    With .FormatConditions(.FormatConditions.Count)
                        .SetFirstPriority
                        .Interior.ColorIndex = 37
                    End With

                End With

            ''''' INCREASE i BY 1 AND LOOP TO AFFECT THE NEXT CELL
            Next i

        ''''' IF THE CELL CHANGED IS NOW 'NO'
        ElseIf target = "No" Then

            ''''' WE DEFINE HOW MANY COLUMNS TO MOVE ACROSS FROM THE CELL THAT CHANGED AND DO THE ACTIONS IN THE CODE BELOW
            For i = 1 To 2

                ''''' MOVE ACROSS i NUMBER OF CELLS FROM THE CELL THAT CHANGED
                With target.Offset(0, i)

                    ''''' SET THE CELL VALUE TO BLANK
                    .Value = ""

                    ''''' LOCK THE CELL
                    .Locked = True

                    ''''' REMOVE THE CONDITIONAL FORMATTING
                    .FormatConditions.Delete

                        ''''' ADD NEW CONDITIONAL FORMATTING HERE IF REQUIRED

                End With

            ''''' INCREASE i BY 1 AND LOOP TO AFFECT THE NEXT CELL
            Next i

        End If

        '''''PROTECT THE SHEET
        ActiveSheet.Protect

    End If

End Sub

请务必在下拉列表所在的 A 列中将锁定设置为 false,否则用户将无法在工作表锁定时更改下拉值。

【讨论】:

  • 代码有效,但似乎有问题。起初它可以工作,但是当我在 A2 中尝试另一个实例时,它不会工作,并且会抛出这个单元格也被锁定的错误。
  • 在我的回答末尾查看我的注释。默认情况下,您的 A 列是锁定的。取消保护工作表(在“查看”选项卡“取消保护工作表”中)然后突出显示 A 列中存在下拉列表的所有单元格并右键单击,格式化单元格,然后单击“保护”选项卡并取消选中“锁定”
  • 谢谢! :),但是如果我需要指定另一个单元格怎么办?例如,我点击“是”,然后我希望另一个像 AA1、AB2 这样的单元格是强制性的,并且单元格 K1 和 P1 是可选的,只有另一种颜色作为可选的指示符?
  • 用大量 cmets 更新了我的答案以解释每个步骤。我鼓励您尝试理解代码,以便根据您的确切要求对其进行操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
相关资源
最近更新 更多