【问题标题】:Excel - Lock Range of Cells Based on ValuesExcel - 根据值锁定单元格范围
【发布时间】:2012-08-10 12:27:22
【问题描述】:

是否可以根据数据行中下拉菜单的输入锁定特定范围的单元格?

例如,我的电子表格的每一行代表一个患者,第一个单元格提出一个问题,需要回答“是”或“否”(通过下拉菜单选择/输入)。

编辑

“是/否”单元格实际上是两个单元格(G13 和 H13)的合并。我更新了我的示例以反映这一点。

编辑结束

如果用户选择“否”,那么我希望锁定问题范围的其余部分(G13-H13:AB13),因为这里不需要输入数据。但是,如果用户选择“是”,则剩余的单元格仍可用于输入数据。

每个范围内的所有单元格都只能通过下拉菜单输入数据。

这是我希望实现的目标:

If "No"
    Then lock range G13-H13:AB13
Else If "Yes"
    Then do nothing

i.e.

 G13-H13  I13-J13  K13-L13   ....     ....     AB13
|  NO   |  ----  |  ----  |  ----  |  ----  |  ----  |  (Locked Cells)

OR

 G13-H13  I13-J13  K13-L13   ....     ....     AB13
|  YES  |        |        |        |        |        |  (Unlocked Cells)

再次强调,所有数据均通过下拉菜单输入,无需手动输入;我希望如果G13-H13 = "No",那么范围内具有下拉列表的其余单元格将被阻止或锁定,无法从它们各自的下拉列表中选择更多信息。

请注意,G13-H13 中的值可以是“是”或“否”。

这可以使用 VBA 实现吗?如果可以,如何实现?

非常感谢。

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    编辑: 您可以在没有 VBA 的情况下执行此操作。我基于这里的另一个答案:https://stackoverflow.com/a/11954076/138938

    G 列有“是”或“否”下拉菜单。

    在单元格 H13 中,像这样设置数据验证:

    1. 数据 --> 数据验证
    2. 允许下拉列表中选择列表
    3. 来源字段中输入此公式:=IF($G13="Yes", MyList, FALSE)
    4. 复制单元格 H13 并将验证(粘贴 --> pastespecial --> 验证)粘贴到单元格 I13:AB13。
    5. 将公式中的MyList 替换为您希望允许用户为每列选择的列表。请注意,您需要将患者答案设置为“是”才能设置验证。设置完成后,您可以将其删除或设置为否。
    6. 为第 13 行设置验证后,将验证复制并粘贴到所有需要它的行。

    如果您想使用 VBA,请使用以下内容,并使用 worksheet_change 事件或其他一些机制来触发 LockOrUnlockPatientCells。我不喜欢使用 worksheet_change,但在这种情况下可能有意义。

    为了锁定单元格,您需要锁定它们,然后保护工作表。下面的代码就是这样做的。您需要将正在处理的患者的行传递给它。

    Sub LockOrUnlockPatientCells(PatientRow As Long)
        Dim ws As Worksheet
        Dim YesOrNo As String
    
        Set ws = ActiveSheet
        YesOrNo = ws.Range("g" & PatientRow).Value
    
        ' unprotect the sheet so that we can modify locked settings
        ws.Unprotect
        ws.Range("a:g").Cells.Locked = False
    
        ' lock row
        Range("h" & PatientRow & ":AB" & PatientRow).Cells.Locked = True
    
        ' unlock the row depending on answer
        If YesOrNo = "Yes" Then
            Range("h" & PatientRow & ":AB" & PatientRow).Cells.Locked = False
        End If
    
        ' protect the sheet again to activate the locked cells
        ws.Protect
    
    End Sub
    

    您可以使用以下方法测试功能,手动调整患者行的值。一旦你让它按照你想要的方式工作,就从用户的输入中获取行。

    Sub testLockedCells()
        Dim AnswerRow As Long
    
        AnswerRow = 9
    
        LockOrUnlockPatientCells AnswerRow
    End Sub
    

    【讨论】:

    • 非常感谢您提供如此详细的回答;不幸的是,我的示例显示了该行的两种可能状态 - G13 的值可以是“是”或“否”,并且根据值是什么,该行的其余部分将可用于编辑(“是” )或将被锁定(“否”)。
    • 啊,我明白了。我编辑了答案以使用单行而不是两行。它还使用 G 列作为“是/否”而不是 A 列。
    • 非常感谢。我已经尝试了新代码,但不幸的是,我仍然可以通过正在审查的行中以下单元格中的下拉菜单选择选项。如果“否”是选择的第一个标准,我希望能够实现的是禁用/禁止用户从行中的任何单元格中选择任何下拉菜单选项。
    • 我编辑了答案以提供我真正喜欢的非 VBA 替代方案。让我知道这是否适合您。
    • 很高兴这有效。我在回答这个问题时学到了一个很酷的技巧!
    【解决方案2】:

    此代码应该可以帮助您入门。您可能需要对其进行调整以满足您的特定需求,但我的逻辑基于您原始帖子中的详细信息。

    将模块放置在 VBE 中的相应工作表对象中。

    Private Sub Worksheet_Change(ByVal Target As Range)
    
    
    'assumes cell changed in column G and first row of data entry is 13
    If Target.Column = 7 And Target.Row > 12 Then 'change to If Intersect(Target, Range("G13")) Then if all you care about is G13
    
    
        Application.EnableEvents = False 'stop events from processing
    
        Dim blnLock As Boolean
        Dim r As Integer
    
        Select Case Target.Value
            Case Is = "No"
                blnLock = True
                r = 191
            Case Is = "Yes"
                blnLock = False
                r = 255
        End Select
    
        Unprotect Password:="myPassword"
    
        With Range("H" & Target.Row & ":AB" & Target.Row)
    
            'just a suggestion, fill the cells grey before locking them, or turn them back to no fill if it's unlocked
            .Interior.Color = RGB(r, r, r)
            .Locked = blnLock
    
        End With
    
        .Protect Password:="myPassword"
    
        Application.EnableEvents = True
    
    End If
    
    
    End Sub
    

    【讨论】:

    • + 1 个好人。三个建议 1) 使用 Intersect 检查单元格 G13 中的值是否发生变化 2) 将 EnableEvents 设置为 false (带有错误处理)并在最后重新设置它们。这是必需的,这样您就不会陷入可能的无限循环。 3) 由于您使用的是Worksheet_Change,因此您实际上不需要为您的工作表声明变量wks
    • 用户想要将答案更改为“是”的原因是什么?该行显示为灰色并锁定。
    【解决方案3】:

    试试这个:-

    应用循环然后检查

    如果“否”

    ws.get_Range(StartCell, EndCell).Locked = true;

    //其中ws是工作表对象唯一需要注意的是,如果Sheet被锁定,你需要解锁它然后继续

    如果“是”则否则

    继续;

    【讨论】:

    • 感谢您的建议,这似乎合乎逻辑。我如何在 VB 中实现这一点?
    • 我给出的答案是一个 c# 代码。对于 VB,您可以尝试 Tushar 下面给出的答案。我希望这应该在您想要实现的目标中发挥作用。
    • @RohitAgrawal,我认为您应该删除此答案。将其发布为 VBA 问题的答案没有任何意义。
    猜你喜欢
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多