如何在同一范围内使用 VBA 进行条件格式化
How to use VBA for conditional formatting on the same range
我正在尝试使用 VBA 在类似范围内进行条件格式化。我确信我的代码中的错误与优先级有关,但我无法弄清楚它是什么。我正在尝试格式化本质上相同的一组单元格。如果列 CI 包含文本 "TIES MATERIAL",那么它应该将单元格格式化,在下面的例子中,在列 CU:DD 中,该特定行的颜色为白色。如果该列不包含文本字符串并且值已从其原始值更改,则应将单元格更改为红色。
这是我将其变为白色的代码:
Private Sub white_format()
'This section adds the formatting condition of white cells to the cells that are changed by the PEMCON
ActiveWorkbook.Sheets("Material").Activate
Dim lRow As Integer
Dim lCol As Integer
lRow = ActiveWorkbook.Sheets("Material").Range("A2").End(xlDown).Row
lCol = ActiveWorkbook.Sheets("Material").Range("A2").End(xlToRight).Column
firstCell = ActiveWorkbook.Sheets("Material").Range("CU3").Address(False, False)
lastCell = ActiveWorkbook.Sheets("Material").Cells(lRow, lCol).Address(False, False)
Debug.Print "firstCell: " & firstCell
Debug.Print "lastHeaderCell: " & lastHeaderCell
Debug.Print "colCount: " & colCount
'Defines the array of the CU3 to the last used cell and it checks to see if the coorisponding cell in column CI has TIES MATERIAL in it
ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions.Add Type:=xlExpression, Formula1:="=$CI3=""TIES MATERIAL"""
ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions(1).SetFirstPriority
With ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = 16777215 'this is the color white
.TintAndShade = 0
End With
ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions(1).StopIfTrue = True
End Sub
这是我将其设为红色的代码:
Private Sub Red_Format()
Dim lRow As Integer
Dim lCol As Integer
lRow = ActiveWorkbook.Sheets("Material").Range("A2").End(xlDown).Row
lCol = ActiveWorkbook.Sheets("Material").Range("A2").End(xlToRight).Column
firstCell = ActiveWorkbook.Sheets("Material").Range("CU2").Address(False, False)
lastCell = ActiveWorkbook.Sheets("Material").Cells(lRow, lCol).Address(False, False)
formatRange = ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell)
lastHeaderCell = ActiveWorkbook.Sheets("Material").Cells(2, lCol).Address(False, False)
colCount = ActiveWorkbook.Sheets("Material").Range(firstCell, lastHeaderCell).Columns.Count
'Defines the array of the CU2 to the last used cell and adds the formatting to turn it red if it has been altered.
ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions.Add Type:=xlExpression, Formula1:="=OFFSET($A,ROW()-1,COLUMN()-1)<>OFFSET($A,ROW()-1,COLUMN()+" & colCount & ")"
'ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions(1).SetFirstPriority
With ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = 255
.TintAndShade = 0
End With
ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions(1).StopIfTrue = False
End Sub
这是我调用 white_format
然后在同一个子例程中调用 red_format
时的条件格式。
公式正确显示,但颜色位于它们需要的相反部分。我做错了什么?我也知道我的代码并不是最高效的 could/should。我还能如何重写它?
Formula1:="=$CI3=""TIES MATERIAL"""
"If column CI contains the text "TIES MATERIAL" then it should format the cell to the color white"
为此,您的格式条件应为:
Formula1:="=ISNUMBER(SEARCH(""TIES MATERIAL"", $CI" & firstCell.Row & "))"
至于第二个条件,我仍然不明白你想要实现的想法。然而,公式可能是正确的,但问题是你错误地引用了它:
With ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions(1).Interior
由于这是 第二个 FormatCondition
,您应该将其称为索引 (2)
。这解释了为什么您实际上用红色覆盖了第一个条件的格式,而第二个条件没有设置格式。
With ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions(2).Interior
' ^^^
(假设您的两个 CF 都适用于同一范围)。如果没有,通常安全的方法是直接获取 CF 上的引用并使用它:
With myRange.formatConditions.Add(xlExpression, formula1)
.Interior.ColorIndex = ...
. etc...
End With
The formulas show up correctly but the colors are in the opposite sections that they need to be in.
这并不完全正确。您创建一个白色背景的 CFR,并将其设置在列表的顶部。然后创建第二个,但在将其置于列表顶部之前,将列表顶部的 CFR 更改为红色背景。所以你有一个 CFR 曾经是白色背景,现在是红色背景,第二个 CFR 没有背景。
我假设红色 CFR 的公式是正确的。其他人建议进行非易失性更改。
Option Explicit
Private Sub white_red_CFRs()
'This section adds the formatting condition of white cells to the cells that are changed by the PEMCON
Dim lRow As Long, lCol As Long, firstCell As String, lastCell As String
Dim colCount As Long, lastHeaderCell As Long
With ActiveWorkbook.Worksheets("Material")
lRow = .Range("A2").End(xlDown).Row
lCol = .Range("A2").End(xlToRight).Column
firstCell = .Range("CU3").Address(False, False)
lastCell = .Cells(lRow, lCol).Address(False, False)
With .Range(firstCell, lastCell)
.FormatConditions.Delete
With .FormatConditions.Add(Type:=xlExpression, Formula1:="=$CI3=""TIES MATERIAL""")
.Interior.Color = 16777215 'this is the color white
.SetFirstPriority
.StopIfTrue = True
End With
With .FormatConditions.Add(Type:=xlExpression, Formula1:="=OFFSET($A,ROW()-1,COLUMN()-1)<>OFFSET($A,ROW()-1,COLUMN()+" & colCount & ")")
.Interior.Color = 255 'this is the color red
.StopIfTrue = True
End With
End With
End With
End Sub
当您记录一个 CFR 时,Excel 将您的操作转换为代码的部分不知道已经有多少个 CFR,因此它将每个 CFR 设为第一个,以便它可以继续配置并参考新的 CFR 为 .FormatConditions(1)
。在将第二个 CFR 设置为最高 (1) CFR 之前,您将格式配置设置为 .FormatConditions(1)
。我更喜欢使用 With .Add 方法。
好的。同样,由于您没有进行测试 material,因此很难理解您试图实现的目标以及出了什么问题(而且这些列太靠右了,我不得不让它变得更简单......),但是可能只有我一个人。
要在列 CI 读取 TIES MATERIAL 时将单元格颜色格式化为白色,您的规则公式“=$CI3=""TIES MATERIAL""" 工作正常但我只是想知道当它们不是白色时它们会是什么颜色?他们会因为其他规则而变红吗?那么它们的顺序是错误的,因为冲突的规则将使规则在列表中的位置更高。 'Stop if true' 适用于 Excel.
的 2007 年前版本
并且可以在图像中看到一个错误,它来自您的代码:在“管理规则”对话框图像中,您看到 'white rule' 被标记为 'No format set'。那是因为您在这两个过程中都引用了 FormatConditions(1)。如果您有第一个 运行 'white rule' 和 'red' 后者已设置为正常但同时打破了第一个(第一个)很可能是因为对范围的引用不匹配。
所以也许您想先 运行 'white rule' 并在创建 'red' 时参考 FormatConditions(2),但正如我所说的很难说。 :-)
我正在尝试使用 VBA 在类似范围内进行条件格式化。我确信我的代码中的错误与优先级有关,但我无法弄清楚它是什么。我正在尝试格式化本质上相同的一组单元格。如果列 CI 包含文本 "TIES MATERIAL",那么它应该将单元格格式化,在下面的例子中,在列 CU:DD 中,该特定行的颜色为白色。如果该列不包含文本字符串并且值已从其原始值更改,则应将单元格更改为红色。
这是我将其变为白色的代码:
Private Sub white_format()
'This section adds the formatting condition of white cells to the cells that are changed by the PEMCON
ActiveWorkbook.Sheets("Material").Activate
Dim lRow As Integer
Dim lCol As Integer
lRow = ActiveWorkbook.Sheets("Material").Range("A2").End(xlDown).Row
lCol = ActiveWorkbook.Sheets("Material").Range("A2").End(xlToRight).Column
firstCell = ActiveWorkbook.Sheets("Material").Range("CU3").Address(False, False)
lastCell = ActiveWorkbook.Sheets("Material").Cells(lRow, lCol).Address(False, False)
Debug.Print "firstCell: " & firstCell
Debug.Print "lastHeaderCell: " & lastHeaderCell
Debug.Print "colCount: " & colCount
'Defines the array of the CU3 to the last used cell and it checks to see if the coorisponding cell in column CI has TIES MATERIAL in it
ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions.Add Type:=xlExpression, Formula1:="=$CI3=""TIES MATERIAL"""
ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions(1).SetFirstPriority
With ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = 16777215 'this is the color white
.TintAndShade = 0
End With
ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions(1).StopIfTrue = True
End Sub
这是我将其设为红色的代码:
Private Sub Red_Format()
Dim lRow As Integer
Dim lCol As Integer
lRow = ActiveWorkbook.Sheets("Material").Range("A2").End(xlDown).Row
lCol = ActiveWorkbook.Sheets("Material").Range("A2").End(xlToRight).Column
firstCell = ActiveWorkbook.Sheets("Material").Range("CU2").Address(False, False)
lastCell = ActiveWorkbook.Sheets("Material").Cells(lRow, lCol).Address(False, False)
formatRange = ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell)
lastHeaderCell = ActiveWorkbook.Sheets("Material").Cells(2, lCol).Address(False, False)
colCount = ActiveWorkbook.Sheets("Material").Range(firstCell, lastHeaderCell).Columns.Count
'Defines the array of the CU2 to the last used cell and adds the formatting to turn it red if it has been altered.
ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions.Add Type:=xlExpression, Formula1:="=OFFSET($A,ROW()-1,COLUMN()-1)<>OFFSET($A,ROW()-1,COLUMN()+" & colCount & ")"
'ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions(1).SetFirstPriority
With ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = 255
.TintAndShade = 0
End With
ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions(1).StopIfTrue = False
End Sub
这是我调用 white_format
然后在同一个子例程中调用 red_format
时的条件格式。
公式正确显示,但颜色位于它们需要的相反部分。我做错了什么?我也知道我的代码并不是最高效的 could/should。我还能如何重写它?
Formula1:="=$CI3=""TIES MATERIAL"""
"If column CI contains the text "TIES MATERIAL" then it should format the cell to the color white"
为此,您的格式条件应为:
Formula1:="=ISNUMBER(SEARCH(""TIES MATERIAL"", $CI" & firstCell.Row & "))"
至于第二个条件,我仍然不明白你想要实现的想法。然而,公式可能是正确的,但问题是你错误地引用了它:
With ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions(1).Interior
由于这是 第二个 FormatCondition
,您应该将其称为索引 (2)
。这解释了为什么您实际上用红色覆盖了第一个条件的格式,而第二个条件没有设置格式。
With ActiveWorkbook.Sheets("Material").Range(firstCell, lastCell).FormatConditions(2).Interior
' ^^^
(假设您的两个 CF 都适用于同一范围)。如果没有,通常安全的方法是直接获取 CF 上的引用并使用它:
With myRange.formatConditions.Add(xlExpression, formula1)
.Interior.ColorIndex = ...
. etc...
End With
The formulas show up correctly but the colors are in the opposite sections that they need to be in.
这并不完全正确。您创建一个白色背景的 CFR,并将其设置在列表的顶部。然后创建第二个,但在将其置于列表顶部之前,将列表顶部的 CFR 更改为红色背景。所以你有一个 CFR 曾经是白色背景,现在是红色背景,第二个 CFR 没有背景。
我假设红色 CFR 的公式是正确的。其他人建议进行非易失性更改。
Option Explicit
Private Sub white_red_CFRs()
'This section adds the formatting condition of white cells to the cells that are changed by the PEMCON
Dim lRow As Long, lCol As Long, firstCell As String, lastCell As String
Dim colCount As Long, lastHeaderCell As Long
With ActiveWorkbook.Worksheets("Material")
lRow = .Range("A2").End(xlDown).Row
lCol = .Range("A2").End(xlToRight).Column
firstCell = .Range("CU3").Address(False, False)
lastCell = .Cells(lRow, lCol).Address(False, False)
With .Range(firstCell, lastCell)
.FormatConditions.Delete
With .FormatConditions.Add(Type:=xlExpression, Formula1:="=$CI3=""TIES MATERIAL""")
.Interior.Color = 16777215 'this is the color white
.SetFirstPriority
.StopIfTrue = True
End With
With .FormatConditions.Add(Type:=xlExpression, Formula1:="=OFFSET($A,ROW()-1,COLUMN()-1)<>OFFSET($A,ROW()-1,COLUMN()+" & colCount & ")")
.Interior.Color = 255 'this is the color red
.StopIfTrue = True
End With
End With
End With
End Sub
当您记录一个 CFR 时,Excel 将您的操作转换为代码的部分不知道已经有多少个 CFR,因此它将每个 CFR 设为第一个,以便它可以继续配置并参考新的 CFR 为 .FormatConditions(1)
。在将第二个 CFR 设置为最高 (1) CFR 之前,您将格式配置设置为 .FormatConditions(1)
。我更喜欢使用 With .Add 方法。
好的。同样,由于您没有进行测试 material,因此很难理解您试图实现的目标以及出了什么问题(而且这些列太靠右了,我不得不让它变得更简单......),但是可能只有我一个人。
要在列 CI 读取 TIES MATERIAL 时将单元格颜色格式化为白色,您的规则公式“=$CI3=""TIES MATERIAL""" 工作正常但我只是想知道当它们不是白色时它们会是什么颜色?他们会因为其他规则而变红吗?那么它们的顺序是错误的,因为冲突的规则将使规则在列表中的位置更高。 'Stop if true' 适用于 Excel.
的 2007 年前版本并且可以在图像中看到一个错误,它来自您的代码:在“管理规则”对话框图像中,您看到 'white rule' 被标记为 'No format set'。那是因为您在这两个过程中都引用了 FormatConditions(1)。如果您有第一个 运行 'white rule' 和 'red' 后者已设置为正常但同时打破了第一个(第一个)很可能是因为对范围的引用不匹配。
所以也许您想先 运行 'white rule' 并在创建 'red' 时参考 FormatConditions(2),但正如我所说的很难说。 :-)