【问题标题】:VBA Excel: Apply conditional formatting to BLANK cellsVBA Excel:将条件格式应用于空白单元格
【发布时间】:2013-11-22 11:17:51
【问题描述】:

我正在尝试编写一个子过程,它将某些条件格式应用于 Excel 中的一系列单元格。 我有点卡住了,所以我使用了宏记录器。但是,我无法弄清楚它为什么要应用下面的公式,而当我手动运行代码时它会失败。

  • 我要做的是对范围内的空白单元格应用条件格式。
  • 我想将单元格颜色设为灰色
  • 范围是一个表,该表称为“Table1”。
  • 我需要在 sub 中执行此操作,因为表会动态刷新。

以下是录制的宏,它不起作用,而是将格式应用于错误的单元格。 任何纠正它的帮助将不胜感激

谢谢

Sub MacroTest()

    Range("Table1").Select
    'The below formula is wrong but I can't figure out what it should be
    Selection.FormatConditions.Add Type:=xlExpression, Formula1:="=LEN(TRIM(D15))=0"
    With Selection.FormatConditions(1).Interior
        .PatternColorIndex = xlAutomatic
        .ThemeColor = xlThemeColorAccent2
        .TintAndShade = 0.399945066682943
    End With
    Selection.FormatConditions(1).StopIfTrue = False

End Sub

【问题讨论】:

  • “错误的单元格”是指它不针对零长度值,还是将格式随机放置在Table 1 中的任何位置?
  • 正确。它不针对零长度值/空白单元格,而是将格式设置在具有日期值的单元格中。我猜这个公式是完全错误的,需要重写。我已经研究过在公式中使用 IsEmpty 和 IsBlank 函数,但无法正确计算出来。
  • @Eddie 我知道这篇文章已经过时了,但是对于未来的访问者来说,一个优雅的解决方案是简单地使用Selection.FormatConditions.Add Type:=xlBlanksCondition 而不需要任何formula1

标签: vba excel conditional-formatting


【解决方案1】:

改变

Selection.FormatConditions.Add Type:=xlExpression, Formula1:="=LEN(TRIM(D15))=0"

Selection.FormatConditions.Add Type:=xlExpression, Formula1:= _
"=LEN(TRIM(C" & Range("Table1").Row & "))=0"

所以你的代码可以写成

Sub Sample()
    With ThisWorkbook.Sheets("Sheet1").Range("Table1")
        .FormatConditions.Add Type:=xlExpression, Formula1:= _
        "=LEN(TRIM(C" & .Row & "))=0"
        .FormatConditions(.FormatConditions.Count).SetFirstPriority
        With .FormatConditions(1).Interior
            .PatternColorIndex = xlAutomatic
            .ThemeColor = xlThemeColorDark2
            .TintAndShade = -9.99481185338908E-02
        End With
    End With
End Sub

【讨论】:

  • 我总是从你那里学到新东西,Sid。不过,只是有点好奇。 .ClearFormats 应该首先清理任何现有的 CF,还是这样做可以吗? :)
  • 感谢您的回复。我正在尝试这两个建议,但得到的结果不一致。也许我的桌子有问题。该表从单元格 B6(第一个标题)开始,然后进入 AO:99。当我尝试上面的代码时,我仍然得到不一致的结果。我已清除所有其他格式条件。我知道上面的公式正在评估单元格的内容,但它甚至会为其中包含数据的单元格着色。
  • @Eddie:Debug.print ThisWorkbook.Sheets("Sheet1").Range("Table1").Address 给了你什么?将“Sheet1”替换为实际工作表名称
  • 显然,CF 是少数需要.Select 的场合之一。在哪里.PasteSpecial xlPasteFormats 闪耀。 @Eddie:请参阅下面的新代码。这是一个简单的解决方法,但它完美无缺。
  • 对我的回复延迟表示歉意。问题出在我的工作表上,而不是效果很好的代码上。谢谢您的帮助。一切都好。
【解决方案2】:

这是我的看法,即使 Sid 已经有了很好的答案。我重新创建了一个名为 test 的表,并将其定位在 A1。我对您的代码进行了少量编辑,对我来说效果很好。

Sub Test()
Dim v As Range
Set v = Range("test")
v.ClearFormats
v.FormatConditions.Add Type:=xlExpression, Formula1:="=LEN(TRIM(A1))=0"
With v.FormatConditions(1).Interior
        .PatternColorIndex = xlAutomatic
        .ThemeColor = xlThemeColorAccent2
        .TintAndShade = 0.399945066682943
End With
v.FormatConditions(1).StopIfTrue = False
End Sub

不过,请注意,在公式中使用 A2 会产生不灵活的结果,尤其是与 Sid 在上面的代码中使用的相比。

希望它有所帮助(或至少提供一些见解)!

第二次:

这件事从前几天就一直困扰着我,所以我再试一次。显然,基于这个Microsoft Support nugget,CF 似乎存在问题。存在两种解决方法:使用绝对引用或在应用 CF 之前先选择单元格。

我玩了一会儿,在绝对参考下得到了很多错误的结果。然而,一种简单的方法是有效的。我们选择Table1的第一个单元格并给它CF,然后我们使用书中最简单的方法:格式刷!我们还将.ClearFormats 替换为.FormatConditions.Delete

以下是使用上述方法的代码变体:

Sub Test()
Dim Table1 As Range: Set Table1 = ThisWorkbook.Sheets("Sheet1").Range("Table1")
    Start = Timer()
    Application.ScreenUpdating = False
    Table1.FormatConditions.Delete
    With Table1.Cells(2, 1)
    'With Range("B7")
        .Select
        .FormatConditions.Add Type:=xlExpression, Formula1:= _
        "=LEN(TRIM(B7))=0"
        .FormatConditions(.FormatConditions.Count).SetFirstPriority
        With .FormatConditions(1).Interior
                .PatternColorIndex = xlAutomatic
                .ThemeColor = xlThemeColorAccent2
                .TintAndShade = 0.399945066682943
        End With
        .FormatConditions(1).StopIfTrue = False
        .Copy
    End With
    Table1.PasteSpecial xlPasteFormats 'or the next one
    'Range("B7:AO99").PasteSpecial xlPasteFormats
    Application.CutCopyMode = False
    Application.ScreenUpdating = True
    Debug.Print Timer() - Start
End Sub

这是结果预览。

执行时间(以秒为单位)为:

  • 4.296875E-02
  • 4.492188E-02
  • 5.273438E-02
  • 5.859375E-02
  • 0.0625

这些比我之前的尝试要快得多,我之前循环遍历所有单元并为每个单元添加 CF。

希望对您有所帮助!

【讨论】:

  • 对您的代码稍作更改 :) 如果您将表格放在 A1 中,那么公式必须是 "=LEN(TRIM(A1))=0" 而不是 "=LEN(TRIM(A2))=0" :) 否则您将得到不正确的结果,如 OP因此.Row 就像我使用的那样:)
  • 很抱歉。我的意思是A1。改了上面的。过去 8 小时一直盯着 SQL 导出,所以我仍然停留在这个标题上。 :D
  • + 1 为.ClearFormats :)
  • @SiddharthRout:虽然我很荣幸接受投票,但我现在质疑.ClearFormats。如果我在单元格中有任何格式,比如可能是货币,它们也会被剥离。现在,我可以在应用 cond 后重新应用它们。格式化,但在某种程度上感觉像是在作弊。 :D
  • @BK201,它确实有帮助。谢谢。
【解决方案3】:

经过一番搜索,我发现了一个不使用函数 LEN 并且需要使用 xlBlanksCondition 指定范围的选项。 如果宏记录器也可以使用 xlBlanksCondition 解决方案,我不明白为什么它会提出 LEN 解决方案。

来源:MSDN Microsoft

我首先选择一个范围,然后应用此代码:

With Selection.FormatConditions.Add(Type:=xlBlanksCondition)
    .StopIfTrue = False
    .Interior.PatternColorIndex = xlAutomatic
    .Interior.Color = RGB(226, 80, 80)
    .Interior.ThemeColor = xlThemeColorAccent2
    .Interior.TintAndShade = 0.39
    .Font.Color = vbBlack
    .Font.TintAndShade = 0
    .Borders.LineStyle = xlContinuous
    .Borders.TintAndShade = 0
    .Borders.Weight = xlThin
    .Borders.Color = RGB(255, 0, 0)
    .StopIfTrue = False
End With

【讨论】:

  • 这应该是公认的答案,因为它不依赖于 Excel 国家语言(在编写公式时),而是依赖于内部 Excel 变量 (xlBlanksCondition)