【问题标题】:VBA Conditional FormattingVBA 条件格式
【发布时间】:2015-02-28 07:59:59
【问题描述】:

我正在努力寻找一种通过 VBA 应用条件格式规则的优雅方法。我更喜欢 VBA,因为 a) 规则将适用于多个工作表,b) 它可以防止在工作表之间复制/粘贴时出现 CF 重复问题。

我有一份库存物品清单,所有物品都保存在不同的位置。我想使用以下格式根据位置进行格式化:

字体颜色(每个位置都会改变);上边框(与字体颜色相同);底部边框(与字体颜色相同)

此外,范围需要是动态的,因为对于每个工作表,它适用于该工作表上的表格。我想对每个适用的工作表应用相同的代码,而不是对每个工作表的表名进行硬编码。

任何帮助将不胜感激。


--更新-- 我尝试修改 J_V 的代码 here,但在公共子的 r.FormatConditions.Add Type:=xlExpression, Formula1:=formula 上收到“运行时错误'5':无效的过程调用或参数”。我不确定边界上的最后一位是否正确,因为运行时会停止宏。我还需要处理动态表引用,但我一次只处理一个问题。

Sub ConditionalFormatting()

Dim myRange As Range
Set myRange = ThisWorkbook.Sheets("Widget1").Range("Widget1_table[Location]")

myRange.FormatConditions.Delete

Call FormatRange(myRange, 10, "=$E5="Warehouse1")
Call FormatRange(myRange, 11, "=$E5="Warehouse2")
Call FormatRange(myRange, 13, "=$E5="Warehouse3")

End Sub

Public Sub FormatRange(r As Range, color As Integer, formula As String)
r.FormatConditions.Add Type:=xlExpression, Formula1:=formula
r.FormatConditions(r.FormatConditions.Count).Font.colorindex = color

With r.FormatConditions(1).Borders(xlTop)
    .LineStyle = xlContinuous
    .Color = color
    .TintAndShade = 0
    .Weight = xlThin
End With
With r.FormatConditions(1).Borders(xlBottom)
    .LineStyle = xlContinuous
    .Color = color
    .TintAndShade = 0
    .Weight = xlThin
End With
r.FormatConditions(1).StopIfTrue = False

End Sub

【问题讨论】:

  • 我首先记录一个将 CF 应用于一个表的宏。然后通过循环浏览工作簿中的每个工作表来展开它,如有必要,还可以通过这些工作表中的每个列表对象(表)进行循环。
  • 将变量命名为与集合属性的保留字相同是一个严重的坏主意。 Formula1:=formula 不建议使用,但 .Color = color 完全错误。
  • 感谢 Jeeped 的提醒,我将重命名变量。

标签: vba excel conditional-formatting


【解决方案1】:

问题实际上不在Sub FormatRange 内,而在于您在Sub ConditionalFormatting 内调用公式时分配公式的方式。该公式包含一个字符串,因此引号必须像这样加倍。

Sub ConditionalFormatting()
    Dim myRange As Range
    Set myRange = ThisWorkbook.Sheets("Widget1").Range("Widget1_table[Location]")

    myRange.FormatConditions.Delete

    Call FormatRange(myRange, 10, "=$E5=""Warehouse1""")
    Call FormatRange(myRange, 11, "=$E5=""Warehouse2""")
    Call FormatRange(myRange, 13, "=$E5=""Warehouse3""")
End Sub

至于第二个宏,当您添加一个新条件时,它会进入队列的底部。如果您查看创建 CF 规则的记录输出,您会看到它通常包含该行,

    Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority

这会将 CF 规则放在队列的顶部,以便之后可以将其称为 .FormatConditions(1)。如果您不希望它位于队列顶部,则必须将其称为队列中的 last,如下所示。

Public Sub FormatRange(r As Range, clr As Integer, frml As String)
    r.FormatConditions.Add Type:=xlExpression, Formula1:=frml
    r.FormatConditions(r.FormatConditions.Count).Font.ColorIndex = clr

    With r.FormatConditions(r.FormatConditions.Count).Borders(xlTop)
        .LineStyle = xlContinuous
        .ColorIndex = clr
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With r.FormatConditions(r.FormatConditions.Count).Borders(xlBottom)
        .LineStyle = xlContinuous
        .ColorIndex = clr
        .TintAndShade = 0
        .Weight = xlThin
    End With
    r.FormatConditions(r.FormatConditions.Count).StopIfTrue = False
End Sub

我还将您的边框 .Color 分配更改为 .ColorIndex,因为 10、1113 似乎是 * 的 ColorIndex 标识符绿色、蓝色和紫色。元音已从变量名称中删除,以避免与集合属性的名称冲突。

【讨论】:

  • Jeeped,非常感谢您所做的更改,因为它们修复了运行时错误。您知道如何将"=$E5=""Warehouse1""") 中的“Warehouse#”引用替换为命名范围引用或来自另一个工作表的引用吗?我现在意识到,如果我可以引用Admin$A$1——其中Warehouse1 存在于列表中——或命名范围Warehouse1,而不是将Warehouse1 硬编码到宏中,那将是最佳选择。
  • 只有 Excel 2010 及更高版本在基于公式创建 CF 规则时允许您使用另一个工作表的单元格地址。对于 Excel 2010 及更高版本,这将类似于 Call FormatRange(myRange, 10, "=$E5='Admin'!$A$1)。命名范围更加通用,可以使用INDEX 分割值,例如Call FormatRange(myRange, 10, "=$E5=INDEX(my_List, 1, 1)")。更好的方法是在您的命名范围内同时包含颜色索引编号和文本字符串,例如 Call FormatRange(myRange, INDEX(my_List, 1, 2), "=$E5=INDEX(my_List, 1, 1)") 如果您遇到问题,请提供详细信息
猜你喜欢
  • 2011-10-02
  • 1970-01-01
  • 2017-03-05
  • 1970-01-01
  • 2018-05-28
  • 2016-10-02
  • 1970-01-01
  • 1970-01-01
  • 2017-11-03
相关资源
最近更新 更多