简体   繁体   English

VBA Excel-使用条件格式锁定/解锁行单元格?

[英]VBA Excel - Row cells locking/unlocking using Conditional formatting?

在此处输入图片说明


Hi, my sheet has 103 columns and 18550 rows of data which is coming from database. 嗨,我的工作表有103列和18550行的数据来自数据库。 Based on B column cells value i have to apply formatting for the respective row like [if B2 value is 1 then for that row interior color should be Orange in color else if it is -1 then it should be in Blue else if it is 0 then the columns F & G should be Green in color and these green coloured cells should not be locked. 基于B列单元格的值,我必须对各行应用格式设置,例如[如果B2值为1,则该行的内部颜色应为橙色,否则为-1,则应为蓝色,否则为0那么F&G列应为绿色,并且这些绿色单元格不应锁定。 And every 1 valued row and the immediate -1 valued rows should be grouped. 并且应将每1个有价值的行和-1个立即价值的行分组。 Currently i have the following code which is almost taking 8 minutes of time to apply formattings. 目前,我有以下代码,几乎需要8分钟的时间来应用格式。


With ThisWorkBook.Sheets("RoAe").Range("A1:A" & rowLen)

'=================For 1 valued Rows==========
Set C = .Find("1", LookIn:=xlValues)
x=0
If Not C Is Nothing Then
    firstAddress = C.Address
    Do
            valR = Split(C.Address, "$")
            actVal = valR(2)
            ReDim Preserve HArray(x)
            HArray(x) = actVal + 1
            x = x + 1


            With ThisWorkBook.Sheets("RoAe").Range("D" & actVal & ":FN" & actVal)
                .Rows.AutoFit
                .WrapText = True
                .Font.Bold = True
                .Interior.Color = RGB(252,213,180) 
                .Borders.Color = RGB(0, 0, 0)
                .HorizontalAlignment = xlCenter
                .VerticalAlignment = xlCenter
            End With

            Set C = .FindNext(C)
    Loop While Not C Is Nothing And C.Address <> firstAddress
End If


'=================For -1 valued Rows==========
Set C = .Find("-1", LookIn:=xlValues)
y=0
If Not C Is Nothing Then
    firstAddress = C.Address
    Do
            valR = Split(C.Address, "$")
            actVal = valR(2)
            ReDim Preserve HArray(y)
            FArray(y) = actVal + 1
            y = y + 1


            With ThisWorkBook.Sheets("RoAe").Range("D" & actVal & ":FN" & actVal)
                .Rows.AutoFit
                .WrapText = True
                .Font.Bold = True
                .Interior.Color = RGB(141,180,226) 
                .Borders.Color = RGB(0, 0, 0)
                .HorizontalAlignment = xlCenter
                .VerticalAlignment = xlCenter
            End With

            Set C = .FindNext(C)
    Loop While Not C Is Nothing And C.Address <> firstAddress
End If


'===================For 0(Zero) Valued Rows============
For p = 0 To UBound(HArray)
    groupRange = "A" & HArray(p) & ":A" & FArray(p)     
    For i = 0 To UBound(arrUnlockMonthStart)
        unlockRange = F & (HArray(p) + 1) & ":" & G & FArray(p)                                                      
        ThisWorkBook.Sheets("RoAe").Range(unlockRange).Locked = False
        ThisWorkBook.Sheets("RoAe").Range(unlockRange).Interior.Color = RGB(216,228,188)
    Next
next

end with
ThisWorkBook.Sheets("RoAe").protect "12345"

Can we do the same with Conditional Formatting. 我们可以对条件格式进行同样的处理吗? Applying format & locking/unlocking for the rows based on cell value. 根据单元格值为行应用格式和锁定/解锁。 Any help would be appreciated greatly. 任何帮助将不胜感激。

As i mentioned that you cannot lock/unlock a cell in conditional formatting. 正如我提到的那样,您不能以条件格式锁定/解锁单元格。 You will have to first apply the conditional formatting and then lock/unlock the cells. 您将必须首先应用条件格式,然后锁定/解锁单元格。 Also you do not need to loop to apply conditional formatting. 另外,您无需循环即可应用条件格式。 You can do that in one go. 您可以一口气做到这一点。

Try this 尝试这个

Option Explicit

Sub Sample()
    Dim ws As Worksheet
    Dim lRow As Long, i As Long
    Dim Rng As Range, unlockRng As Range

    '~~> Set this to the relevant worksheet
    Set ws = ThisWorkbook.Sheets("Sheet1")

    With ws
        '~~> Find the last row in Col B
        lRow = .Range("B" & .Rows.Count).End(xlUp).Row

        '~~> Set your range where CF will be applied for -1/1
        Set Rng = .Range("D2:H" & lRow)

        With Rng
            .FormatConditions.Add Type:=xlExpression, Formula1:="=$B2=1"
            .FormatConditions(1).SetFirstPriority
            With .FormatConditions(1).Interior
                .PatternColorIndex = xlAutomatic
                .ThemeColor = xlThemeColorAccent6
                .TintAndShade = 0.399945066682943 '<~~ Orange
            End With
            .FormatConditions(1).StopIfTrue = True

            .FormatConditions.Add Type:=xlExpression, Formula1:="=$B2=-1"
            .FormatConditions(2).SetFirstPriority
            With .FormatConditions(1).Interior
                .PatternColorIndex = xlAutomatic
                .ThemeColor = xlThemeColorLight2
                .TintAndShade = 0.599993896298105 '<~~ Blue
            End With
            .FormatConditions(1).StopIfTrue = True
         End With

         '~~> Set your range where CF will be applied for 0
         Set Rng = .Range("F2:G" & lRow)

         With Rng
            .FormatConditions.Add Type:=xlExpression, Formula1:="=$B2=0"
            .FormatConditions(3).SetFirstPriority
            With .FormatConditions(1).Interior
                .PatternColorIndex = xlAutomatic
                .ThemeColor = xlThemeColorAccent3
                .TintAndShade = 0.399975585192419 '<~~ Green
            End With
            .FormatConditions(1).StopIfTrue = True
         End With

         '~~> Loop through cells in Col B to checl for 0 and store
         '~~> relevant Col F and G in a range
         For i = 2 To lRow
            If .Range("B" & i).Value = 0 Then
                If unlockRng Is Nothing Then
                    Set unlockRng = .Range("F" & i & ":G" & i)
                Else
                    Set unlockRng = Union(unlockRng, .Range("F" & i & ":G" & i))
                End If
            End If
         Next i
    End With

    '~~> unlock the range in one go
    If Not unlockRng Is Nothing Then unlockRng.Locked = False
End Sub

ScreenShot 截图

在此处输入图片说明

EDIT 编辑

For 103 Columns and 18550 Rows use this method. 对于103 Columns18550 Rows使用此方法。 This is much faster than the above 这比上面要快得多

Option Explicit

Sub Sample()
    Dim ws As Worksheet
    Dim lRow As Long, i As Long
    Dim Rng As Range, unlockRng As Range

    '~~> Set this to the relevant worksheet
    Set ws = ThisWorkbook.Sheets("Sheet1")

    Application.ScreenUpdating = False

    With ws
        '~~> Find the last row in Col B
        lRow = .Range("B" & .Rows.Count).End(xlUp).Row

        '~~> Set your range where CF will be applied for -1/1
        '~~> Taking 103 Columns into account
        Set Rng = .Range("D2:DB" & lRow)

        With Rng
            .Locked = True

            .FormatConditions.Delete

            .FormatConditions.Add Type:=xlExpression, Formula1:="=$B2=1"
            .FormatConditions(1).SetFirstPriority
            With .FormatConditions(1).Interior
                .PatternColorIndex = xlAutomatic
                .ThemeColor = xlThemeColorAccent6
                .TintAndShade = 0.399945066682943 '<~~ Orange
            End With
            .FormatConditions(1).StopIfTrue = True

            .FormatConditions.Add Type:=xlExpression, Formula1:="=$B2=-1"
            .FormatConditions(2).SetFirstPriority
            With .FormatConditions(1).Interior
                .PatternColorIndex = xlAutomatic
                .ThemeColor = xlThemeColorLight2
                .TintAndShade = 0.599993896298105 '<~~ Blue
            End With
            .FormatConditions(1).StopIfTrue = True
         End With

         '~~> Set your range where CF will be applied for 0
         Set Rng = .Range("F2:G" & lRow)

         With Rng
            .FormatConditions.Add Type:=xlExpression, Formula1:="=$B2=0"
            .FormatConditions(3).SetFirstPriority
            With .FormatConditions(1).Interior
                .PatternColorIndex = xlAutomatic
                .ThemeColor = xlThemeColorAccent3
                .TintAndShade = 0.399975585192419 '<~~ Green
            End With
            .FormatConditions(1).StopIfTrue = True
         End With

         '~~> Loop through cells in Col B to check for 0 and 
         '~~> unlock the relevant range
         For i = 2 To lRow
            If .Range("B" & i).Value = 0 Then
                .Range("F" & i & ":G" & i).Locked = False
            End If
         Next i
    End With

    Application.ScreenUpdating = True
End Sub

As far as I know, the locking and grouping cannot be done with Conditional Formatting, the coloring however can be done. 据我所知,锁定和分组不能使用条件格式进行,但是可以进行着色。

You can color a cell based oa formula entered in conditional formatting dialog and this formula can contain relative, semi-relative and absolute references to other cells (using the $ notation as in any other formulas). 您可以为在条件格式对话框中输入的基于单元格的公式着色,并且该公式可以包含对其他单元格的相对,半相对和绝对引用(与其他任何公式一样,都使用$表示法)。

For example the "make row orange if column B = 1" can be done by setting condition formatting in cell D2 to formula =if($B1=1;TRUE;FALSE) . 例如,可以通过将单元格D2中的条件格式设置为公式=if($B1=1;TRUE;FALSE)来完成“如果列B = 1,则使行变为橙色”。 If you put the $ in front of B as in this example, than you can apply the conditional formatting to the whole range columns D:H and it should color the lines as your script does. 如果在本例中将$放在B的前面,则可以将条件格式应用于整个范围列D:H,它应该像脚本一样对行进行着色。

Doing all the colors is just repeating the process and setting more conditional formating rules with different formulas. 完成所有颜色只是重复该过程,并使用不同的公式设置更多的条件格式设置规则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM