Highlighting the Active Row and Column

July 6, 2009 by datapig Leave a reply »

Today, I'd like to take time out of my busy day and help Preet, who writes:

"How can I highlight the column and row of my current cell? If i am in cell J4 and want to highlight column J and row 4, what is the shortcut for it?"

As far as I know Preet, there is no 'Shortcut' to automatically highlight the active cell/column. If there is a way, I'm sure one of you won't hesitate to point it out, making me feel like a complete ass.

In any case, VBA is the solution I came up with:

Copy this code and paste it into the worksheet's 'SelectionChange' event. This procedure dynamically creates new conditional formatting rules that tell Excel to highlight the current row and column.

Visual Basic:
  1. 'Highlights the active row
  2. With ActiveSheet.Cells
  3. .FormatConditions.Delete
  4. .FormatConditions.Add Type:=xlExpression, _
  5. Formula1:="=ROW(A" & ActiveCell.Row & ") = " & ActiveCell.Row
  6. .FormatConditions(1).Interior.ColorIndex = 36
  7. End With
  8. 'Highlights the active column
  9. With ActiveSheet.Cells
  10. .FormatConditions.Add Type:=xlExpression, _
  11. Formula1:="=column(" & Mid(Left(ActiveCell.Address, InStr(2, ActiveCell.Address, "$")-1), 2, 10) & "1) = " & ActiveCell.Column
  12. .FormatConditions(2).Interior.ColorIndex = 36
  13. End With



Once the code is in place, Excel will highlight the row and column for the cell that is active.  This kind of effect can help when viewing or editing a large grid.

Of course, there are a couple of caveats.

First, when you highlight a range, don't expect the range's cross section to be highlighted. That requires some other mumbo-jumbo that I'm not prepared to tackle. Only the last activated cell will be affected.

Secondly, you'll notice the code clears all conditional formatting before doing its magic. This means that you should probably not use this on a sheet that already has conditional formatting.

That's it Preet. Now go tell everyone how awesome I am.

*******UPDATE********

Dan came up with an excellent alternative to coloring or conditional formatting the cells.  In his procedure, Dan simply selects a range made up of the selected column and row.  Fantastic.

Visual Basic:
  1. Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  2. Dim str As String
  3. On Error Resume Next
  4. With Target
  5. If .Count = 1 Then
  6. str = .Address & "," & .Row & ":" & .Row _
  7. & "," & Left(.Address, InStr(2, .Address, "$") - 1) & ":" _
  8. & Left(.Address, InStr(2, .Address, "$") - 1)
  9. End If
  10. End With
  11. Range(str).Select
  12. On Error GoTo 0
  13. End Sub

RELATED STUFF

  1. Zoom into Spreadsheet on Double-Click
  2. Mocking the ‘Merge & Center’ Icon
  3. VBE Tips I Wish I Knew 5 Years Ago
  4. Exploding a Dataset using a PivotTable
Advertisement

30 Responses

  1. Jayson says:

    It's actually a lot easier than that.

    Ctrl+spacebar will select the column and shift+spacebar will select the row.

    for an impressive list of shortcuts: http://office.microsoft.com/en-us/excel/HP052037811033.aspx

  2. Joseph says:

    @Jayson

    Yeah, but if you try to do both, it selects the entire set of data or the entire worksheet.

  3. DataPig says:

    Jayson: Thanks for the link. I don't think you can highlight both row and column at the same time. That is why I assumed Preet wanted to color the row and column - not simpy activate them.

  4. Jayson says:

    didn't see that... hmmm

  5. jamescox says:

    This seems to work like the initial code, but avoids stomping all over previous Conditional Formatting:

    At the top of each sheet's code module:

    Private sPrevRow As String
    Private sPrevCol As String

    Private Sub Worksheet_SelectionChange(ByVal Target As Range)

    Dim sTarAddr As String
    Dim sRow As String
    Dim sCol As String

    If sPrevRow "" Then
    Range(sPrevCol & ":" & sPrevCol).Interior.ColorIndex = -4142
    Range(sPrevRow & ":" & sPrevRow).Interior.ColorIndex = -4142
    End If

    ' On Error Resume Next
    If Target.Cells.Count > 1 Then Set Target = Target.Cells(1)
    If Err 0 Then Exit Sub

    sTarAddr = Target.Address(0, 0)
    sRow = CStr(Target.Row)
    sCol = Left$(sTarAddr, Len(sTarAddr) - Len(sRow))
    Range(sCol & ":" & sCol).Interior.ColorIndex = 34
    Range(sRow & ":" & sRow).Interior.ColorIndex = 34

    sPrevCol = sCol
    sPrevRow = sRow

    End Sub

    I had to throw in the On Error Resume Next because clicking on the 'A zero cell' to select the whole worksheet gave me an overflow error on Target.Cells.Count

  6. jamescox says:

    Oops - remove the comment character from the

    ' On Error Resume Next

    line - was testing and forgot to clear that...

  7. DataPig says:

    JamesCox: Valiant effort. But it does seem that your approach stomps on any existing interior cell formatting.

    I think the lesser of two evils is the condtional formatting approach.

  8. MikeyRoRO says:

    DataPig,

    Love the blog. Keep up the great work!

  9. jamescox says:

    Not necessarily to argue with you (but it does drive your blog's stats up!) - which is easier to re-do: setting up Conditional Formatting or clicking on a cell and changing the fill color? Also, since it wipes out the Conditional Formatting of cells whose Conditional Formatting hadn't caused a change in the default cell or text color, it's less obvious that those have been deleted than is a cell color change.

    Of course, which is the lesser evil probably depends more on which (Conditional Formatting or cell color) the OP uses the most...

  10. jaymz says:

    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Cells.ClearFormats
    With Target
    .EntireRow.Interior.ColorIndex = 36
    .EntireColumn.Interior.ColorIndex = 36
    End With
    End Sub

  11. Preet says:

    Mike,

    Thanks! This is what I was looking for. I was wrong about the short-cut.

  12. Dan says:

    MIKE - TRY THIS MATE...

    Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

    Dim str As String
    On Error Resume Next
    With Target
    If .Count = 1 Then
    str = .Address & "," & .Row & ":" & .Row _
    & "," & Left(.Address, InStr(2, .Address, "$") - 1) & ":" _
    & Left(.Address, InStr(2, .Address, "$") - 1)
    End If
    End With
    Range(str).Select
    On Error GoTo 0

    End Sub

  13. datapig says:

    Dan: This is fantastic! This is definitely better than my method. I've added an update to the post.

  14. jamescox says:

    Great, Dan!

    A marvelous example of giving the OP what he wanted, not what he asked for .

  15. xcel_star says:

    DAN guru,

    Tussi great ho (you are great),
    Your July8 post is great. It does not affect the existing cell colours.

    I have been looking for this for years, and think that your code should be a standard feature in all future spreadsheet software.

    I am just yet a power-user, on learning curve to VBA.

    Kindly help me for
    1) how to make it available to all sheet.
    2) how to make it like an add-in with switch on/off type

    I have used RowLiner (http://www.cpearson.com/excel/RowLiner.htm) and Andrew's cell spotter, but you code is great

    Thanking you in advance
    xcel_star, India

  16. Dan says:

    Yeah this is possible... It will require programming the VBE though. I'll give Mike a shout when I've managed it - see if he wants to provide a link or something.

  17. Hi Mike,

    Very cool blog :-)

    FYI, I've done some similar stuff before using the CELL function. Note Undo is not affected.

    http://blog.livedoor.jp/andrewe/archives/17936306.html
    http://blog.livedoor.jp/andrewe/archives/50061563.html

  18. Dan says:

    Only way i can figure is to programme the VBE (I tool the code from Chip Pearson - http://www.cpearson.com). If anyone knows of a simplier way let me know. Run SelectRowCol procedure to enable row/col highlight and again to turn it off.

    Private Sub Workbook_BeforeClose(Cancel As Boolean)
    ThisWorkbook.Names("Selection").Delete
    DeleteProcedureFromModule
    End Sub

    Private Sub Workbook_Open()
    ActiveWorkbook.Names.Add Name:="Selection", RefersToR1C1:="=0"
    End Sub

    Option Explicit
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
    (ByVal ClassName As String, ByVal WindowName As String) As Long

    Private Declare Function LockWindowUpdate Lib "user32" _
    (ByVal hWndLock As Long) As Long

    Sub CreateEventProcedure()
    Dim VBProj As VBIDE.VBProject
    Dim VBComp As VBIDE.VBComponent
    Dim CodeMod As VBIDE.CodeModule
    Dim LineNum As Long
    Dim wks As Worksheet
    Application.ScreenUpdating = False
    Application.VBE.MainWindow.Visible = False
    Set VBProj = ActiveWorkbook.VBProject
    For Each wks In Worksheets
    Set VBComp = VBProj.VBComponents(wks.Name)
    Set CodeMod = VBComp.CodeModule
    With CodeMod
    LineNum = .CreateEventProc("SelectionChange", "Worksheet")
    LineNum = LineNum + 1
    .InsertLines LineNum, "Dim str As String"
    LineNum = LineNum + 1
    .InsertLines LineNum, "On Error Resume Next"
    LineNum = LineNum + 1
    .InsertLines LineNum, "With Target"
    LineNum = LineNum + 1
    .InsertLines LineNum, "If .Count = 1 Then"
    LineNum = LineNum + 1
    .InsertLines LineNum, "str = .Address &" & Chr(34) & "," & Chr(34) & "& .Row &" & Chr(34) & ":" & Chr(34) & " & .Row &" & Chr(34) & "," & Chr(34) & " & Left(.Address, InStr(2, .Address," & Chr(34) & "$" & Chr(34) & ") - 1) & " & Chr(34) & ":" & Chr(34) & " & Left(.Address, InStr(2, .Address, " & Chr(34) & "$" & Chr(34) & ") - 1)"
    LineNum = LineNum + 1
    .InsertLines LineNum, "End If"
    LineNum = LineNum + 1
    .InsertLines LineNum, "End With"
    LineNum = LineNum + 1
    .InsertLines LineNum, "Range(str).Select"
    LineNum = LineNum + 1
    .InsertLines LineNum, "On Error GoTo 0"
    End With
    Next wks
    End Sub

    Sub DeleteProcedureFromModule()
    Dim VBProj As VBIDE.VBProject
    Dim VBComp As VBIDE.VBComponent
    Dim CodeMod As VBIDE.CodeModule
    Dim StartLine As Long
    Dim NumLines As Long
    Dim ProcName As String
    Dim wks As Worksheet

    Set VBProj = ActiveWorkbook.VBProject

    On Error Resume Next
    For Each wks In Worksheets
    Set VBComp = VBProj.VBComponents(wks.Name)
    Set CodeMod = VBComp.CodeModule

    ProcName = "Worksheet_SelectionChange"
    With CodeMod
    StartLine = .ProcStartLine(ProcName, vbext_pk_Proc)
    NumLines = .ProcCountLines(ProcName, vbext_pk_Proc)
    .DeleteLines StartLine:=StartLine, Count:=NumLines
    End With
    Next wks
    On Error GoTo 0
    End Sub

    Sub EliminateScreenFlicker()
    Dim VBEHwnd As Long
    On Error GoTo ErrH:
    Application.ScreenUpdating = False
    Application.VBE.MainWindow.Visible = False

    VBEHwnd = FindWindow("wndclass_desked_gsk", _
    Application.VBE.MainWindow.Caption)

    If VBEHwnd Then
    LockWindowUpdate VBEHwnd
    End If
    CreateEventProcedure
    Application.VBE.MainWindow.Visible = False
    ErrH:
    LockWindowUpdate 0&
    End Sub

    Sub SelectRowCol()

    Dim S As String
    S = ThisWorkbook.Names("Selection").RefersTo
    S = Mid(S, 2)

    If S = "1" Then
    Call DeleteProcedureFromModule
    ActiveWorkbook.Names.Add Name:="Selection", RefersToR1C1:="=0"
    Else
    Call EliminateScreenFlicker
    ActiveWorkbook.Names.Add Name:="Selection", RefersToR1C1:="=1"
    End If

    End Sub

  19. Bass says:

    Hi Dan,

    I paste your last code to excel, but when executed it said "Compile error : Only comments may appear after End Sub, End Function, or End Property. "

    How to fix it?

  20. Bass says:

    Fyi, it stops here:

    Option Explicit
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
    (ByVal ClassName As String, ByVal WindowName As String) As Long

    Please advice. Thank you.

  21. Dan says:

    To get the row & column select thin to work in ANY worksheet put the following event procedure in the ThisWorkbook code module:

    Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)

    Dim str As String
    On Error Resume Next
    With Target
    If .Count = 1 Then
    str = .Address & "," & .Row & ":" & .Row _
    & "," & Left(.Address, InStr(2, .Address, "$") - 1) & ":" _
    & Left(.Address, InStr(2, .Address, "$") - 1)
    End If
    End With
    Sh.Range(str).Select
    On Error GoTo 0
    End Sub

  22. Rick Rothstein (MVP - Excel) says:

    This should do the same thing as Dan's code posted on July 8, 2009...

    Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    Union(Target.EntireColumn, Target.EntireRow).Select
    Target.Activate
    End Sub

    If you would want this code in the SelectionChange event, then you would need to add the test for Target.Count>1 and surround the code with Application.EnableEvents=False and Application.EnableEvents=True to stop the code from selecting everything.

  23. datapig says:

    Rick: Very nice!

  24. Rick Rothstein (MVP - Excel) says:

    Thanks datapig, I'm glad you liked it. Too bad I didn't find your website sooner because then other readers here would have had a better chance of seeing it (while the topic was "fresh"). For those interested (mainly so you can just copy/paste it), here is the SelectionChange event version of my code (this duplicates the functionality of Dan's code that you posted in the Update to your blog)...

    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Count > 1 Then Exit Sub
    Application.EnableEvents = False
    Union(Target.EntireColumn, Target.EntireRow).Select
    Target.Activate
    Application.EnableEvents = True
    End Sub

    Now, brace yourself, because I think you are going to **really** be surprised by this next piece of code. Here is a **very short** SelectionChange event procedure that duplicates (the best I can tell) the functionality of your blog's originally posted code (turning the active cell's row and column yellow)...

    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Cells.Interior.ColorIndex = 0
    Union(Target.EntireColumn, Target.EntireRow).Interior.ColorIndex = 36
    End Sub

  25. Rick Rothstein (MVP - Excel) says:

    Actually, on the last code I posted (the one that makes the active cell's row and column yellow), there is one major difference from your originally posted code... if you select a range of cells, then my code makes all the rows and all the columns associated with the range become highlighted whereas your code only highlights the active cell (within the range)'s row and column.

  26. Bass says:

    the Ctrl+C or copy command does not work if the highlight function is active. is there any way to fix it?

  27. Staple1600 says:

    Here is the "simplified" SelectionChange event version (this duplicates the functionality of Dan's code that you posted in the Update to your blog)

    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim str$
    On Error Resume Next
    With Target
    str = _
    IIf(.Count = 1, _
    .Address & "," & .EntireRow.Address & "," & .EntireColumn.Address, _
    Target.Address)
    End With
    Range(str).Select
    On Error GoTo 0
    End Sub

    PS: I've just read Rick Rothstein's solution
    ('http://datapigtechnologies.com/blog/index.php/highlighting-the-active-row-and-column/comment-page-1/#comment-2402') after I write my answer.
    Sorry for that (and for my english because I'm a french guy and my english speaking is weak)

  28. Bob Phillips says:

    Very late to the party, but another way.

    Select all of the cells in the target area and add CF with a formula of

    =OR(ROW()=CELL("row"),COLUMN()=CELL("col"))

    and the colour of your choice.

    Then add event code of

    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Application.ScreenUpdating = True
    End Sub

  29. Larry says:

    Alternatively,

    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    On Local Error Resume Next
    With Target
    If .Count = 1 Then
    With .Cells
    s = .Address & "," & .EntireColumn.Address & "," & .EntireRow.Address
    Range(s).Select
    End With
    End If
    End With
    On Local Error GoTo 0
    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>