【问题标题】:Excel VBA Multiple Conditional FormattingExcel VBA 多条件格式
【发布时间】:2016-10-02 18:19:19
【问题描述】:

我是 VBA 新手。我知道这不是做我正在做的事情的最佳方式,所以任何关于改进想法和一般方法解释的帮助将不胜感激!

所以我想要三种不同的格式。小于、大于和空白单元格格式。

几乎我的代码运行在一行中,检查每个值与该行末尾的值(目标)。如果大于或等于目标,则变为绿色。如果它较小,则为红色。如果目标单元格为空,则所有单元格均为空白(格式为白色背景,黑色文本)。如果单元格为空,则该单元格为空白(白色背景)。

我按顺序运行了所有 5 个宏,小、大、相等、空目标、空单元。这创建了一个格式正确且外观漂亮的 Excel。

当您更改目标编号时,该行中的单元格将分别更改。伟大的!但是,当您向以前的空目标添加新编号或删除目标编号时,您必须重新运行宏以获取格式。

旁注:对于我的代码,我记录了自己在做我想要的一行(除了空单元格),然后将它变成一个循环,沿着其他行向下。

知道如何消除重新运行的宏吗?理想情况下,此 Excel 文档将发送给对 VBA 一无所知的人。

Sub Greater()
Dim i As Integer
Dim myRange As String
Dim myComparison As String
For i = 4 To 97
    myRange = "C" & i & ":BC" & i
    myComparison = "=$BD$" & i
    Range(myRange).Select
    Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlGreater, _
        Formula1:=myComparison
    Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
    With Selection.FormatConditions(1).Font
        .Color = -16752384
        .TintAndShade = 0
    End With
    With Selection.FormatConditions(1).Interior
        .PatternColorIndex = xlAutomatic
        .Color = 13561798
        .TintAndShade = 0
    End With
    Selection.FormatConditions(1).StopIfTrue = False
    Next i
End Sub

x

Sub Lesser()
Dim i As Integer
Dim myRange As String
Dim myComparison As String
For i = 4 To 97
    myRange = "C" & i & ":BC" & i
    myComparison = "=$BD$" & i
    Range(myRange).Select
    Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlLess, _
        Formula1:=myComparison
    Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
    With Selection.FormatConditions(1).Font
        .Color = -16383844
        .TintAndShade = 0
    End With
    With Selection.FormatConditions(1).Interior
        .PatternColorIndex = xlAutomatic
        .Color = 13551615
        .TintAndShade = 0
    End With
    Selection.FormatConditions(1).StopIfTrue = False
    Next i
End Sub

x

Sub Equal()
Dim i As Integer
Dim myRange As String
Dim myComparison As String
For i = 4 To 97
    myRange = "C" & i & ":BC" & i
    myComparison = "=$BD$" & i
    Range(myRange).Select
    Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlEqual, _
        Formula1:=myComparison
    Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
    With Selection.FormatConditions(1).Font
        .Color = -16752384
        .TintAndShade = 0
    End With
    With Selection.FormatConditions(1).Interior
        .PatternColorIndex = xlAutomatic
        .Color = 13561798
        .TintAndShade = 0
    End With
    Selection.FormatConditions(1).StopIfTrue = False
    Next i
End Sub

x

Sub EmptyGoal()
Dim i As Integer
Dim myRange As String
Dim myComparison As String
For i = 4 To 97
    myRange = "C" & i & ":BC" & i
    Range(myRange).Select
    Selection.FormatConditions.Add Type:=xlExpression, Formula1:=IsEmpty(Cells(i, 56))
    Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
    With Selection.FormatConditions(1).Font
        .ThemeColor = xlThemeColorLight1
        .TintAndShade = 0
    End With
    With Selection.FormatConditions(1).Interior
        .PatternColorIndex = xlAutomatic
        .ThemeColor = xlThemeColorDark1
        .TintAndShade = 0
    End With
    Selection.FormatConditions(1).StopIfTrue = False
    Next i
End Sub

x

Sub EmptyCell()
    Range("C4:BC97").Select
    Selection.FormatConditions.Add Type:=xlExpression, Formula1:= _
        "=LEN(TRIM(C4))=0"
    Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
    With Selection.FormatConditions(1).Interior
        .PatternColorIndex = xlAutomatic
        .ThemeColor = xlThemeColorDark1
        .TintAndShade = 0
    End With
    Selection.FormatConditions(1).StopIfTrue = False
End Sub

【问题讨论】:

  • 不看数据就很难准确理解你在做什么,但我认为你可以将格式应用到整个数据集一次,使用 4 或 5具有优先顺序的条件。无需循环行,甚至无需编写任何宏。您可以使用“公式”选项以包含可能更改的方式编写规则。

标签: excel conditional-formatting vba


【解决方案1】:
  1. 为什么不添加一个调用它们的宏呢?然后在工作表的某处设置一个按钮来运行它。 (PS:您可以轻松地在同一个 Sub 中完成所有操作,并且对于不需要遍历每个单元格的所有单元格(您现在这样做是因为您使用 ($$) 设置绝对引用,这在Excel,只需锁定列就可以了)
  2. 附带说明,如果您在为条件格式设置的原始范围中删除范围,然后在其间添加/删除某些内容,则条件格式可能会针对这些范围拆分(如果指定的范围未锁定,它会更改,并且它是Excel 的预期行为)。但是,如果您对整个列执行此操作,则如果用户添加行,则不会发生任何事情——这意味着,添加的行将保留条件格式——(添加/删除列时行的原则相同)。

例如,您可以将这些 subs 用于 GreaterLesserAndEqual。

Sub AddConditionalFormating()
Dim myRange As Range: Set myRange = Range("C4:BC97")
myRange.FormatConditions.Delete
Call AddGreaterLesserAndEqual(xlGreater, 198, 239, 206, 0, 97, 0)
Call AddGreaterLesserAndEqual(xlLess, 156, 0, 6, 255, 199, 206)
Call AddGreaterLesserAndEqual(xlEqual, 0, 97, 0, 198, 239, 206)
End Sub
Sub AddGreaterLesserAndEqual(OperatorToEvalaute, RColorFonT As Long, GColorFont As Long, BColorFont As Long, RInteriorColor As Long, GInteriorColor As Long, BInteriorColor As Long)
Const myComparison = "=$BD1"
Dim myRange As Range: Set myRange = Range("C4:BC97")
myRange.FormatConditions.Add Type:=xlCellValue, Operator:=OperatorToEvalaute, _
Formula1:=myComparison
myRange.FormatConditions(myRange.FormatConditions.Count).SetFirstPriority
myRange.FormatConditions(1).Font.Color = RGB(RColorFonT, GColorFont, BColorFont)
myRange.FormatConditions(1).Interior.Color = RGB(RInteriorColor, GInteriorColor, BInteriorColor)
myRange.FormatConditions(1).StopIfTrue = False
End Sub

【讨论】:

    【解决方案2】:

    不确定我是否迟到了这个节目,但我想我会加两分钱。我相信您在单元格未更新时遇到的部分问题与此代码Selection.FormatConditions.Add Type:=xlExpression, Formula1:=IsEmpty(Cells(i, 56)) 有关。这里发生的是 VBA 正在计算此表达式 IsEmpty(Cells(i, 56)) 为 TRUE 或 FALSE,然后将该布尔值放入您的条件格式中。那些,它永远不会更新,因为 TRUE 总是 TRUE 并且 FALSE 总是 FALSE。使用类似于你的其他表达式的东西在这里可以工作=LEN(TRIM(C4))=0

    另外,有趣的事实可能会帮助您在未来的marco-ing。您可以输入Cells(i, 56) 或Cells(i, "BD"),excel 将正确处理它。有时我很难记住当我稍后回到代码时是哪一列。

    条件格式的另一件很酷的事情是,您可以在条件中添加一个公式,Excel 会像处理单元格中的公式一样对其进行推断。意思是,如果单元格“A1”包含=SUM(B1:C1),并且您复制该单元格并将其粘贴到单元格“A2”中,“A2”现在将包含=SUM(B2:C2),并且美元符号会将地址的那部分冻结到该位置。所以 $A1 将使列保持“A”,但允许行更改。但 A$1 将允许列更改但行保持不变。最后是$A$!将使其成为“绝对”位置,因此列或行不会改变。

    这也适用于条件格式的条件。如果您创建公式=C4=$BD4,则 C4 将其视为=C4=$BD4,但 C5 将其视为=C5=$BD5,最后 D6 将其视为=D6=$BD6。因此,使用这些知识,您实际上不需要执行 for 循环来遍历所有行,只需正确使用 $ 即可。

    考虑到所有这些,我编写了以下代码,它应该与您之前的代码相同,并且希望也更具可读性。

    注意事项,您目前的 Cell=Goal 和 Cell>Goal 的格式相同,这可能只是一种条件格式,即 Cell>=Goal,但我将它们分开,因此您可能会为每个格式设置单独的格式未来的状况。此外,xlThemeColorLight1 和 Dart1 在我的 Excel 中只是显示为白色,所以我不确定您实际上希望它们是什么颜色。但是如果你知道颜色的索引号,你可以使用.Color = RGB(XXX, XXX, XXX)或.Color = XXXXXXX。

        Sub CombinedMacro()
    
        Dim ws As Worksheet
        Dim rng1 As Range, rng2 As Range
        Dim rowStart As Integer, rowEnd As Integer
    
        Set ws = ActiveSheet
        rowStart = 14
        rowEnd = 17
    
        Set rng1 = ws.Range("C" & rowStart & ":BC" & rowEnd)
        Set rng2 = ws.Range("BD" & rowStart & ":BD" & rowEnd)
    
        rng1.FormatConditions.Delete
        rng2.FormatConditions.Delete
    
        With rng1
            'Condition if cell is empty
            .FormatConditions.Add xlExpression, , "=LEN(TRIM(C" & rowStart & "))=0"
            With .FormatConditions(1)
                .Interior.Color = vbYellow
                .StopIfTrue = False
            End With
    
            'Condition if cell is equal to goal
            .FormatConditions.Add xlExpression, , "=C" & rowStart & "=$BD" & rowStart
            With .FormatConditions(2)
                .Font.Color = 24832 'positive version of -16752384
                .Interior.Color = 13561798
                .StopIfTrue = False
            End With
    
            'Condition if cell is less than goal
            .FormatConditions.Add xlExpression, , "=C" & rowStart & "<$BD" & rowStart
            With .FormatConditions(3)
                .Font.Color = 393372 'positive version of -16383844
                .Interior.Color = 13551615
                .StopIfTrue = False
            End With
    
            'Condition if cell is greater than goal
            .FormatConditions.Add xlExpression, , "=C" & rowStart & ">$BD" & rowStart
            With .FormatConditions(4)
                .Font.Color = 24832 'positive version of -16752384
                .Interior.Color = 13561798
                .StopIfTrue = False
            End With
        End With
    
        With rng2
            'Condition if goal is empty
            .FormatConditions.Add xlExpression, , "=LEN(TRIM(BD" & rowStart & "))=0"
            With .FormatConditions(1)
                .Interior.Color = vbBlue
                .StopIfTrue = False
            End With
        End With
    
    End Sub
    

    哦,另外,对于您添加到该范围的每个条件,FormatCondition(#) 都会增加 1。所以它们会按照你创建它们的顺序发生,我看到你使用的是Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority,但这只是改变了顺序。所以在代码中改变它们的顺序应该有同样的效果。

    我希望这对你有帮助。祝你好运!

    【讨论】:

      猜你喜欢
      • 2017-11-03
      • 2011-10-02
      • 2017-10-05
      • 2017-03-03
      • 2017-03-05
      • 2012-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多