VBA – 当列值发生变化(甚至是过滤)时更改行着色

我试图编写一个macros来更改列B中的值更改时行的颜色。 列A将是我的控制列,使用1和0,即只要列B保持不变,列A将保持1; 每当B改变时,A将翻转到0,依此类推。

当B列中的值发生更改时,我可以正确地将行正确着色,但是当过滤数据时会出现问题。 例如:假设我的B2-B4设置为“test1”,B5-B7设置为“test2”,B8-B10设置为“test3”,那么我将B列过滤为不包含“test2”。 最初,在列值改变的地方,行的着色方式不同,但B2-B4和B8-B10行被设置为相同的颜色,现在它们因为“test2”行被隐藏而触摸。

这里是我用来给行着色的代码,但是它不适用于过滤:

Sub ColorRows() Dim This As Long Dim Previous As Long Dim LastRow As Long Dim Color As Integer Dim R As Long LastRow = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row RwColor = Array(15,0) Color = 0 For R = 2 To LastRow This = Cells(R, 1).Value Previous = Cells(R - 1, 1).Value If This <> Previous Then Color = 1 - Color Range("A" & R & ":M" & R).Select Selection.Interior.ColorIndex = RwColor(Color) Next R End Sub 

我怎样才能解决这个问题,即使在过滤之后,在列值发生变化的时候,这些行也能正确着色?

这是一个方法来做到这一点:

1.)将以下代码作为UDF插入到代码模块中。
2.)然后把公式放在A中,如A2: =analyseVisible(B2)

这将比较B细胞和上面的下一个可见细胞,并在A产生一个“排名”计数器。

现在A中的计数器是连续的(即使行被隐藏),您可以使用MOD 2使用条件格式对其进行着色:

3.)添加一个条件格式(从整个表的A2): =MOD($A2,2)=1并设置填充颜色。

如果您现在使用filter或更改B中的值,那么行将实时重新着色。

 Public Function analyseVisible(r As Range) As Integer Dim i As Long If Application.Caller.Row <= 2 Or _ r.Row <> Application.Caller.Row Then analyseVisible = 1 Exit Function End If i = r.Row - 1 While r.Worksheet.Rows(i).Hidden And i > 1 i = i - 1 Wend If i = 1 Then analyseVisible = 1 Else analyseVisible = r.Worksheet.Cells(i, Application.Caller.Column).Value If r.Worksheet.Cells(i, r.Column).Value <> _ r.Value Then analyseVisible = analyseVisible + 1 End If End Function 

下面的代码通过只检查使用的&可见的行来处理这个问题。 它工作得很好,但我无法弄清楚如何在filter更改时触发它。 它也直接对正在改变的值进行比较。

 Private Sub colorRows() Dim this As Variant Dim previous As Variant Dim currentColor As Long Dim rng As Range 'visible range Dim c As Range ' cell ' pick a color to start with currentColor = vbYellow ' rng = used and visible cells Set rng = ActiveSheet.UsedRange.SpecialCells(xlCellTypeVisible) For Each c In rng ' For each cell that is visible and used If Not c.Row = 1 Then ' skip header row this = c.Value 'some simple test logic to switch colors If this <> previous Then If currentColor = vbBlue Then currentColor = vbYellow ElseIf currentColor = vbYellow Then currentColor = vbBlue End If End If 'set interior color c.Interior.color = currentColor previous = this End If Next c End Sub 

然后,在要着色的工作表模块中,从Worksheet_Activate()事件调用该子。 (事实上​​,你可能想要一个不同的事件,我主要是和Access一起工作的,所以我真的不知道你有什么可用的东西,我只是想告诉你正确的方向,我敢肯定你的下一个问题是否坚持你开始使用的方法。)

 Private Sub Worksheet_Activate() colorRows End Sub