根据其他单元格中的条件锁定单元格

时间:2015-05-06 20:29:01

标签: excel vba excel-vba

我有一个电子表格,用于管理各种项目所需的文档和信息。我想根据在另一个单元格中输入的信息对这些单元格中的一些进行着色和锁定。

在我详细介绍之前,我应该提一下,我对宏和VBA都是全新的,所以我的知识非常基础。这些列可能会发生变化,因此除了代码之外,我想知道如何编辑代码以包含其他列或如何删除它们。此外,我将需要申请超过500行数据,最终产品将受到保护。

我添加了一个类似于我实际工作的文档的链接(由于我公司的安全限制,我无法上传原文)。他是我目前需要满足的条件:

  • 如果在“Single Source”列中选择B,则需要锁定E-HP-R列。
  • 除了“≤ $50k”之外,如果在“≤ $100k”列中选择了C“Single Source”,则列F将被锁定。
  • C中的下拉列表可能会更改为手动输入的估算价格,因为当前范围可能会发生变化。
  • 如果在“Bid”列中选择了B,并且在“≤ $50k”列中选择了“≤ $100k”C,则列P-R& AC需要锁定
  • L5&如果列A5位于C
  • 下,$2M个审批将被锁定
  • L4&如果列A4位于C
  • 下,$1M个审批将被锁定
  • L3&如果列A3位于C
  • 下,$500k个审批将被锁定
  • L2&如果列A2位于C
  • 下,$50k个审批将被锁定
  • L2& A2批准永远不会被锁定。

到目前为止,我在网上找到的任何代码都没有成功,因为我无法成功编辑它们以满足我的需求,所以任何帮助都将不胜感激。

https://www.dropbox.com/s/9memoq1hcab2a4e/Document%20Control_Test.xlsm?dl=0

1 个答案:

答案 0 :(得分:0)

作为参考,UserForm是一个VBA可以打开的表单,有点像应用程序的精简版本。作为UserForm(在幕后)的一个示例是Excel向您展示的任何错误提示。您可以从Visual Studio for Applications窗口在Excel中创建自己的。

在开始如何做你想做的事情之前,你提到你希望C列是一个允许用户输入值的下拉列表。 Excel工作表不允许这样做。它可以是下拉列表,也可以是用户输入的值,它不能同时为两者。鉴于在某些情况下选项列表可能不够,您应该将其设置为用户输入的单元格(即没有下拉选项),然后验证宏中输入的值。

你可以使用直接的宏来做你想要的事情,并且鉴于你对VBA代码应该做的变化的评论,我将成为异教徒,并说这可能是更易于维护的方法。

要完成这项工作,您需要编辑工作表代码以添加事件处理程序,特别是Worksheet_Change

从那里你应该检查更改的单元格是否应该导致宏运行的单元格。根据您问题中的详细信息,您需要在B列和B列中查找单元格。 C,像这样

IF LEFT(Target.Address, 3) = "$B$" OR LEFT(Target.Address, 3) = "$C$" THEN

此时,调用一个实际执行繁重工作的不同函数并将行号传递给它可能是有意义的。例如:

FormatMgmt(RIGHT(Target.Address, LEN(TARGET.Address) - 3), ActiveSheet.Name)

然后给你一个解决问题的例子,让你知道如何做你列出的所有事情

Sub FormatMgmt(rn as long, WSName as String)
    '
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets(ActiveSheet.Name)
    Dim CC As Range
    Set CC = ws.Range("C" & rn) 'I'm using a variable to refer to column C since we'll
        'need to use this cell quite a bit

    Application.ScreenUpdating 'Prevent Excel from updating what's displayed on your
        'computer monitor. This lets the macro run faster

    'Determine what's in Column B for the identified row
    Select Case LCase(ws.Range("B" & rn).Value) 'LCase forces all text to lower case, so
        'that capitalization doesn't mess up the comparison
        Case "single source"
            'Protect Columns E-H & P-R
            ws.Unprotect ("<whatever_your_password_is>") 'The password is optional, but
                'you need to unlock the sheet to change whether cells are protected

            ws.Range("E" & rn & ":H" & rn).Locked = True

            'Check if column F needs locked. Note, you said if <=50k OR <=100k selected
            'should do this. Since I'm assuming a user entered value, I have to take the
            'tigher constraint
            If CC.Value <= 50000 Then
                'Lock column F.
                ws.Range("F" & rn).Locked = True
            End If

            'Check if L3, L4, L5, A3, A4, or A5 need locked. Note: you're last bullet
            'says A2 & L2 should never be locked, which contradicts the bullet
            'immediately prior. I assumed the later bullet took precedence. Also, I
            'assumed the conditions in the last 5 bullets stacked (i.e. CC < $500k means
            'A3-A5 & L3-5 should be locked)
            If CC.Value < 2000000 Then
                ws.Range("L5").Locked = True
                ws.Range("A5").Locked = True
            End If

            If CC.Value < 1000000 Then
            '...
            'Fill in the rest of the code here. You should have enough to start
            '...
            'NOTE: Be sure to put in appropriate logic to UNDO any of the cell locking
            'if a cell's value changes as well

        'Relock the sheet
        WS.Protect"<whatever_your_password_is>")

        'At the very end of the macro be sure to turn screen updating back on (no
        'good doing all this if it doesn't show on the screen)
        Application.ScreenUpdating = True
End Sub

这应该足以让你开始。如果没有,请谷歌搜索更具体的问题,你应该很快得到答案(这就是我学习VBA,VB.net,C#,SQL等的方法。)