Irregular Color Banding on Double Click

February 20, 2012 by datapig Leave a reply »

I recently worked on a project where there was the need to sort on columns and band the rows based on the data in the table. That is to say, color the rows in alternate colors based on the data in each sorted column. The issue is that there is not a set pattern to the rows. This makes the color banding irregular.

.

I came up with a nifty macro that automatically sorts and bands the rows each time a user double-clicks a column. Both the sorting and color banding is based on the column that is double-clicked. There probably is a more elegant way to apply the color banding, but this works for me.

.

.

To do the same with your data, simply copy and paste this code into the Before_Doubleclick event of the worksheet.

.

Visual Basic:
  1. Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
  2. Dim LastRow As Long
  3. Dim MyCell As Range
  4. Dim CurrentColor As Integer
  5.  
  6. Const WHITE As Integer = 2
  7. Const GREEN As Integer = 35
  8.  
  9. 'Find last row
  10.     LastRow = Cells(Rows.Count, 1).End(xlUp).Row
  11.  
  12. 'Sort ascending on double-click column
  13.     Rows("2:" & LastRow).Sort _
  14.     Key1:=Cells(2, ActiveCell.Column), _
  15.     Order1:=xlAscending
  16.  
  17. 'Start Color
  18.     CurrentColor = GREEN
  19.  
  20. 'Loop through cells in double-clicked column
  21.     For Each MyCell In Range(Cells(2, ActiveCell.Column), Cells(LastRow, ActiveCell.Column)).Cells
  22.  
  23. 'Check to see if value is different from previous cell
  24.         If MyCell = MyCell.Offset(-1, 0) Then
  25.  
  26.             'If same, then use same color
  27.             MyCell.EntireRow.Interior.ColorIndex = CurrentColor
  28.         Else
  29.  
  30.             'If different, then determine alternate color
  31.             Select Case CurrentColor
  32.                 Case Is = GREEN
  33.                     CurrentColor = WHITE
  34.                 Case Else
  35.                     CurrentColor = GREEN
  36.             End Select
  37.  
  38.             'Apply alternate color
  39.             MyCell.EntireRow.Interior.ColorIndex = CurrentColor
  40.         End If
  41.     Next MyCell
  42.      
  43. End Sub

.

Notes:

  1. Be aware that the code assumes that column headers start on A1.
  2. As written, the code works best where the data is a contiguous range with nothing else on the sheet. You will have to adjust the code if this is not the case in your situation.
  3. The color banding will not overtake any Conditional Formatting, but it will completely blow away any cell coloring you have on your sheet.
  4. You can download the sample file here.

.

Enjoy!

Advertisement

6 Responses

  1. sam says:

    Assuming you have Description starting from C2:C20
    The alternate irregular banding can be achieved via Conditional Formatting using the below formula

    =ROUND(MOD(SUM(1/COUNTIF(C2:C$20,C2:C$20)),2),0)=1 - Apply Light Green Format

    For Sorting we could apply a filter click on the drop down a say Sort A to Z

    For making it Dynamic you could define it as a List(2003) or a Table (2007/2010)

    VBA ??? :-)

  2. Rick Rothstein (MVP - Excel) says:

    Here is code I have used in the past to do this (I commented it for presentation here)... it uses a For..Next rather than a For Each..Next loop and uses a different method to swap the colors back and forth. Since a user can only double click a single cell, I chose to use Target rather than ActiveCell when determining the column to sort on. Unlike your code, my code tests to make sure the code only reacted to a double-click on the header row and, because of this restriction, I use Cancel=True to stop that action from entering edit mode. Okay, here is the code...

    Visual Basic:
    1. Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    2.   Dim X As Long, LastRow As Long, Color As Long
    3.   Const FirstColor As Long = 2   'White
    4.   Const SecondColor As Long = 35 'Green
    5.   Const ColorSum As Long = FirstColor + SecondColor
    6.  
    7.   '  Make sure the double-click took place in the header row
    8.   If Target.Row> 1 Then Exit Sub
    9.  
    10.   '  Find last row
    11.   LastRow = Cells(Rows.Count, "A").End(xlUp).Row
    12.  
    13.   '  Sort ascending on double-click column
    14.   Rows("2:" & LastRow).Sort Key1:=Cells(2, Target.Column), Order1:=xlAscending
    15.  
    16.   '  Set opposite color from the one you want first
    17.   Color = SecondColor
    18.  
    19.   '  Loop through cells in double-clicked column
    20.   For X = 2 To LastRow
    21.  
    22.     '  If current cell differs from previous cell, then swap colors
    23.     If Cells(X, Target.Column).Value <> Cells(X - 1, Target.Column) Then Color = ColorSum - Color
    24.  
    25.     '  Color the cell with the currently selected color
    26.     Rows(X).Interior.ColorIndex = Color
    27.  
    28.   Next
    29.   Cancel = True
    30. End Sub

  3. Rick Rothstein (MVP - Excel) says:

    Follow up question... how come the code you posted in your blog article has large colored text, is nicely indented and its window is horizontally scrollable whereas the code I posted using tags is none of those things. How can we get our code to look like the code you posted (obviously tags are not the way)?

  4. datapig says:

    Rick: it looks like the only tags that will create the nice codeframe is the vb /vb tags (in brackets)

    I applied them to your code.

  5. Rick Rothstein (MVP - Excel) says:

    Thanks for converting the code for me (looks like the indenting got kind of messed up though). There is no "Plain Text" tags listed in your tag list... is that a set of tags a commenter can apply? Also, I think you used the actual tags (angle brackets and all) in your reply as they got converted to an empty "Plain Text" box. Can you post the tags without the angle brackets so the next person to post code can try it and see if it works or not?

  6. Bob_D says:

    Rick Rothstein:
    I do like the extra line limiting the double-click to the header row.

    datapig: I liked the code except that I dislike the entire row being highlighted. Not being an MVP, (so excuse the code if it is not optimum) I coded the following to limit the row highlighting:

    Visual Basic:
    1. Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    2. Dim LastRow As Long
    3. Dim LastCol As Long
    4. Dim MyCell As Range
    5. Dim MyCells As Range
    6. Dim CurrentColor As Integer
    7. Dim MyRow As Integer
    8.  
    9. Const WHITE As Integer = 2
    10. Const GREEN As Integer = 35
    11. If Target.Row> 1 Then Exit Sub
    12. 'Find last row
    13.     LastRow = Cells(Rows.Count, 1).End(xlUp).Row
    14. ' Find last column
    15.     LastCol = Cells.Find(What:="*", SearchDirection:=xlPrevious, SearchOrder:=xlByColumns).Column
    16.  
    17. 'Sort ascending on double-click column
    18.     Rows("2:" & LastRow).Sort _
    19.     Key1:=Cells(2, ActiveCell.Column), _
    20.     Order1:=xlAscending
    21.  
    22. 'Start Color
    23.     CurrentColor = GREEN
    24.  
    25. 'Loop through cells in double-clicked column
    26.     For Each MyCell In Range(Cells(2, ActiveCell.Column), Cells(LastRow, ActiveCell.Column)).Cells
    27.         MyRow = MyCell.Row
    28.        
    29. 'Check to see if value is different from previous cell
    30.         If MyCell = MyCell.Offset(-1, 0) Then
    31.  
    32.             'If same, then use same color
    33.             For Each MyCells In Range(Cells(MyRow, 1), Cells(MyRow, LastCol)).Cells
    34.                MyCells.Interior.ColorIndex = CurrentColor
    35.               Next MyCells
    36.         Else
    37.  
    38.             'If different, then determine alternate color
    39.             Select Case CurrentColor
    40.                 Case Is = GREEN
    41.                     CurrentColor = WHITE
    42.                 Case Else
    43.                     CurrentColor = GREEN
    44.             End Select
    45.  
    46.             'Apply alternate color
    47.             For Each MyCells In Range(Cells(MyRow, 1), Cells(MyRow, LastCol)).Cells
    48.                MyCells.Interior.ColorIndex = CurrentColor
    49.              Next MyCells
    50.         End If
    51.     Next MyCell
    52.  
    53. End Sub

Leave a Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

*

* Copy this password:

* Type or paste password here:

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>