使用 Excel VBA 根据每个单元格中的值自动设置行格式?
Autoformat row based on values in each cell using Excel VBA?
我有表 1
A 列有一个日期,例如2017 年 5 月 30 日
B 列具有状态,例如 "Success"
C 列有值,例如 500
要求:在更改单元格时在 VBA 中应用自定义条件格式
假设更改发生在第 5 行的 A、B 或 C 列中
无论A列、B列还是C列发生变化,都应该执行相同的逻辑。
如果A列的值小于Now(),那么第5行应该是红底白字。 运行.
无需进一步检查
否则,如果 B 列为 "Success",则第 5 行应为绿色背景和白色文本。 运行.
无需进一步检查
否则,如果 C 列的值小于 500,则第 5 行应为蓝色背景和白色文本。 运行.
无需进一步检查
下面的 VBA 代码用于检查单元格上的更改 - 它使用超链接自动格式化 b 列中的单元格。
我现在需要的是根据上述标准自动格式化整行。
Private Sub Worksheet_Change(ByVal Target As Range)
If ((Not Intersect(Target, Range("B:B")) Is Nothing) Or (Not Intersect(Target, Range("F:F")) Is Nothing) Or (Not Intersect(Target, Range("G:G")) Is Nothing) Or (Not Intersect(Target, Range("I:I")) Is Nothing)) Then
End If
End Sub
试试这个代码:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Rng As Range, R As Range
Dim fCol As Long, bCol As Long
Set Rng = Application.Intersect(Target, Columns("A:C"))
If Not Rng Is Nothing Then
Set Rng = Application.Intersect(Rng.EntireRow, Columns("A:C"))
fCol = vbWhite
For Each R In Rng.Rows
If R.Cells(1, 1).Value <> vbNullString And R.Cells(1, 1).Value < Now Then
bCol = vbRed
ElseIf R.Cells(1, 2).Value <> vbNullString And R.Cells(1, 2).Value = "Success" Then
bCol = vbGreen
ElseIf R.Cells(1, 3).Value <> vbNullString And R.Cells(1, 3).Value < 500 Then
bCol = vbBlue
Else
bCol = xlNone
fCol = vbBlack
End If
R.EntireRow.Interior.Color = bCol
R.EntireRow.Font.Color = fCol
Next
End If
End Sub
编辑:
I have Table1
如果 Table1 是 ListObject
(Excel tables) 那么我们可以修改上面的代码,让它监视这个 table 的前三列,而不管第一列从哪里开始(在 "A" 或 "B" 等列中),并且仅格式化 table 行而不是 EntireRow :
Private Sub Worksheet_Change(ByVal Target As Range)
Dim LObj As ListObject
Dim RngToWatch As Range
Dim Rng As Range, R As Range
Dim fCol As Long, bCol As Long
Set LObj = ListObjects("Table1") ' the name of the table
Set RngToWatch = Range(LObj.ListColumns(1).DataBodyRange, LObj.ListColumns(3).DataBodyRange)
Set Rng = Application.Intersect(Target, RngToWatch)
If Not Rng Is Nothing Then
Set Rng = Application.Intersect(Target.EntireRow, RngToWatch)
fCol = vbWhite
For Each R In Rng.Rows
If R.Cells(1, 1).Value <> vbNullString And R.Cells(1, 1).Value < Now Then
bCol = vbRed
ElseIf R.Cells(1, 2).Value <> vbNullString And R.Cells(1, 2).Value = "Success" Then
bCol = vbGreen
ElseIf R.Cells(1, 3).Value <> vbNullString And R.Cells(1, 3).Value < 500 Then
bCol = vbBlue
Else
bCol = xlNone
fCol = vbBlack
End If
With Application.Intersect(LObj.DataBodyRange, R.EntireRow)
.Interior.Color = bCol
.Font.Color = fCol
End With
Next
End If
End Sub
我假设您的 table(具有三列)出现在 Sheet1 中。
因此,在 Sheet1 中添加以下代码(不在单独的模块中)
Private Sub Worksheet_Change(ByVal Target As Range)
Dim irow As Variant
' First identify the row changed
irow = Target.Row
' Invoke row formatter routine
Call DefineFormat(irow)
End Sub
然后在模块中添加如下代码(也可以在Sheet1下添加,但会限制该模块的使用)
Sub DefineFormat(irow) ' Receive the row number for processing
Dim vVal As Variant
Dim Rng As Range
Dim lFont, lFill As Long
' Define the basis for validation
Dim Current, Success, limit As Variant ' Can be defined as constant as well
Current = Date ' Set today's date
Success = "Success" ' Set success status check
limit = 500 ' Set limit for value check
' Set range for the entire row - Columns A(index 1) to Column C (index 3)
Set Rng = Range(Application.ActiveSheet.Cells(irow, 1).Address, Application.ActiveSheet.Cells(irow, 3).Address)
lFont = vbWhite
' Assuming columns A, B and C needs to be formatted
If Application.ActiveSheet.Cells(irow, 1) < Current Then
lFill = vbRed ' Check for col A
Else:
If Application.ActiveSheet.Cells(irow, 2) = Success Then
lFill = vbGreen ' Check for col B
Else
If Application.ActiveSheet.Cells(irow, 3) < limit Then
lFill = vbBlue ' Check for col C
Else ' Default formatting
lFill = xlNone
lFont = vbBlack
End If
End If
End If
Rng.Interior.Color = lFill
Rng.Font.Color = lFont
End Sub
这将在修改数据时格式化该行(就像条件格式一样)
此外,如果您需要一次性格式化整个 table,那么您可以在循环中为 table 的每一行调用 DefineFormat 例程,如 Fadi 在他的回复中所示。
我有表 1
A 列有一个日期,例如2017 年 5 月 30 日
B 列具有状态,例如 "Success"
C 列有值,例如 500
要求:在更改单元格时在 VBA 中应用自定义条件格式
假设更改发生在第 5 行的 A、B 或 C 列中
无论A列、B列还是C列发生变化,都应该执行相同的逻辑。
如果A列的值小于Now(),那么第5行应该是红底白字。 运行.
无需进一步检查否则,如果 B 列为 "Success",则第 5 行应为绿色背景和白色文本。 运行.
无需进一步检查否则,如果 C 列的值小于 500,则第 5 行应为蓝色背景和白色文本。 运行.
无需进一步检查下面的 VBA 代码用于检查单元格上的更改 - 它使用超链接自动格式化 b 列中的单元格。
我现在需要的是根据上述标准自动格式化整行。
Private Sub Worksheet_Change(ByVal Target As Range)
If ((Not Intersect(Target, Range("B:B")) Is Nothing) Or (Not Intersect(Target, Range("F:F")) Is Nothing) Or (Not Intersect(Target, Range("G:G")) Is Nothing) Or (Not Intersect(Target, Range("I:I")) Is Nothing)) Then
End If
End Sub
试试这个代码:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Rng As Range, R As Range
Dim fCol As Long, bCol As Long
Set Rng = Application.Intersect(Target, Columns("A:C"))
If Not Rng Is Nothing Then
Set Rng = Application.Intersect(Rng.EntireRow, Columns("A:C"))
fCol = vbWhite
For Each R In Rng.Rows
If R.Cells(1, 1).Value <> vbNullString And R.Cells(1, 1).Value < Now Then
bCol = vbRed
ElseIf R.Cells(1, 2).Value <> vbNullString And R.Cells(1, 2).Value = "Success" Then
bCol = vbGreen
ElseIf R.Cells(1, 3).Value <> vbNullString And R.Cells(1, 3).Value < 500 Then
bCol = vbBlue
Else
bCol = xlNone
fCol = vbBlack
End If
R.EntireRow.Interior.Color = bCol
R.EntireRow.Font.Color = fCol
Next
End If
End Sub
编辑:
I have Table1
如果 Table1 是 ListObject
(Excel tables) 那么我们可以修改上面的代码,让它监视这个 table 的前三列,而不管第一列从哪里开始(在 "A" 或 "B" 等列中),并且仅格式化 table 行而不是 EntireRow :
Private Sub Worksheet_Change(ByVal Target As Range)
Dim LObj As ListObject
Dim RngToWatch As Range
Dim Rng As Range, R As Range
Dim fCol As Long, bCol As Long
Set LObj = ListObjects("Table1") ' the name of the table
Set RngToWatch = Range(LObj.ListColumns(1).DataBodyRange, LObj.ListColumns(3).DataBodyRange)
Set Rng = Application.Intersect(Target, RngToWatch)
If Not Rng Is Nothing Then
Set Rng = Application.Intersect(Target.EntireRow, RngToWatch)
fCol = vbWhite
For Each R In Rng.Rows
If R.Cells(1, 1).Value <> vbNullString And R.Cells(1, 1).Value < Now Then
bCol = vbRed
ElseIf R.Cells(1, 2).Value <> vbNullString And R.Cells(1, 2).Value = "Success" Then
bCol = vbGreen
ElseIf R.Cells(1, 3).Value <> vbNullString And R.Cells(1, 3).Value < 500 Then
bCol = vbBlue
Else
bCol = xlNone
fCol = vbBlack
End If
With Application.Intersect(LObj.DataBodyRange, R.EntireRow)
.Interior.Color = bCol
.Font.Color = fCol
End With
Next
End If
End Sub
我假设您的 table(具有三列)出现在 Sheet1 中。 因此,在 Sheet1 中添加以下代码(不在单独的模块中)
Private Sub Worksheet_Change(ByVal Target As Range)
Dim irow As Variant
' First identify the row changed
irow = Target.Row
' Invoke row formatter routine
Call DefineFormat(irow)
End Sub
然后在模块中添加如下代码(也可以在Sheet1下添加,但会限制该模块的使用)
Sub DefineFormat(irow) ' Receive the row number for processing
Dim vVal As Variant
Dim Rng As Range
Dim lFont, lFill As Long
' Define the basis for validation
Dim Current, Success, limit As Variant ' Can be defined as constant as well
Current = Date ' Set today's date
Success = "Success" ' Set success status check
limit = 500 ' Set limit for value check
' Set range for the entire row - Columns A(index 1) to Column C (index 3)
Set Rng = Range(Application.ActiveSheet.Cells(irow, 1).Address, Application.ActiveSheet.Cells(irow, 3).Address)
lFont = vbWhite
' Assuming columns A, B and C needs to be formatted
If Application.ActiveSheet.Cells(irow, 1) < Current Then
lFill = vbRed ' Check for col A
Else:
If Application.ActiveSheet.Cells(irow, 2) = Success Then
lFill = vbGreen ' Check for col B
Else
If Application.ActiveSheet.Cells(irow, 3) < limit Then
lFill = vbBlue ' Check for col C
Else ' Default formatting
lFill = xlNone
lFont = vbBlack
End If
End If
End If
Rng.Interior.Color = lFill
Rng.Font.Color = lFont
End Sub
这将在修改数据时格式化该行(就像条件格式一样)
此外,如果您需要一次性格式化整个 table,那么您可以在循环中为 table 的每一行调用 DefineFormat 例程,如 Fadi 在他的回复中所示。