Excel VBA多条件格式

时间:2016-06-02 20:31:30

标签: excel excel-vba conditional-formatting vba

我是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

2 个答案:

答案 0 :(得分:0)

  1. 为什么不添加一个全部调用它的宏?然后在工作表中的某个位置设置一个按钮来运行它。 (PS:您可以轻松地在同一个Sub中执行所有操作,并且对于您不需要循环遍历每个单元格的所有单元格(您现在这样做,因为您使用($$)设置绝对引用,这可用作在Excel中的公式,只需锁定列,你就可以了。)
  2. 在旁注中,如果删除条件格式设置的原始范围中的范围,然后在其间添加/删除某些内容,则条件格式可能会针对这些范围进行拆分(范围如果指定未锁定,则会更改并且&# 39; s Excel的预期行为。但是,如果您对整个列执行此操作,则在用户添加行时没有任何反应 - 这意味着,条件格式将保留为添加的行 - (添加/删除列时行的原则相同)。
  3. 例如,您可以使用这些子代替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
    

答案 1 :(得分:0)

我不确定我是否会迟到这个节目,但我想我会加上我的两分钱。我相信你的细胞没有更新的部分问题与此代码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

中使用

此外,有趣的事实可能会帮助您在未来的市场化。您可以放置​​Cells(i, 56)Cells(i, "BD"),excel会正确处理它。有时我很难记住以后回到代码时的哪一列。

关于条件格式化的另一个很酷的事情是你可以在一个条件中放置一个公式,而excel会像在单元格中的公式一样推断它。意思是,如果Cell" A1"包含=SUM(B1:C1)并复制该单元格并将其粘贴到Cell" 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>目标格式相同,这可能只是一个条件格式,即Cell> = Goal,但我将它们分开,所以你可能有单独的格式未来的状况。另外xlThemeColorLight1和Dart1在我的excel上显示为White,所以我不确定你真正希望它们是什么颜色。但是,如果您知道颜色的索引号,则可以使用.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,但这只是改变了顺序。因此,在代码中更改其顺序应具有相同的效果。

我希望这会对你有所帮助。快乐的马克思!