Forum Discussion
VBA code to change (revert) Cell Colour when clicking out of cell (ie not the active cell)
- Feb 06, 2023
Netrix650 << … when I click away from it >>
The Excel object model does not support just a Click event (it does support DoubleClick and RightClick events), so it appears that you should use the SelectionChange event of the "floor" worksheets. (So you will advance from writing macro code to writing event handler code, and get more experience with VBA objects.) Such code is also written using the Visual Basic Editor (VBE), which offers some additional object-oriented assistance, as you will see below.
If you were modeling just one floor, or otherwise were using just one "floor" worksheet, you could do handle this more simply. But to handle "green cells" on multiple spreadsheets at once…
Your FindDesk procedure needs some modifications, as here:
Sub FindDesk() Dim deskNo As String Dim objSheet As Worksheet '---- Grab the user-specified desk identifier. deskNo = ActiveCell.Value 'MsgBox deskNo '---- Select the worksheet that should contain that desk identifier, ' based on a floor number encoded at its start. ' If the identifier is "not valid", warn the user and exit. If Left(deskNo, 1) = 1 Then Set objSheet = Sheets("First floor") ElseIf Left(deskNo, 1) = 2 Then Set objSheet = Sheets("Second floor") ElseIf Left(deskNo, 1) = 4 Then Set objSheet = Sheets("Fourth floor") Else Call MsgBox(deskNo & " is not a recognized identifier." _ , vbExclamation Or vbOKOnly) Exit Sub End If objSheet.Select '---- Locate the next cell (there probably should be just one) that ' contains the desk identifier. ' [I would expect an error handler to be enabled here, if not earlier, ' unless other code ensures that the deskNo will be found.] Cells.Find(What:=deskNo, After:=ActiveCell, LookIn:=xlFormulas2, LookAt:= _ xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _ , SearchFormat:=False).Activate 'NEED CODE HERE TO REVERT CELL TO ORIGINAL BACKGROUND WHEN IT IS NOT THE ACTIVE CELL ' [This is probably not the place to do that. After all, doing that ' here would mean you would have to call this procedure again to clear ' the highlighting. ' However, this is the place to capture the cell's address or reference, ' and its about-to-be-changed color.] Call CallByName(objSheet, "CaptureCurrentStuff", VbMethod, ActiveCell) '---- Highlight that cell in green. [You can replace vbGreen with the ' RGB function for some lighter or mixed-color shade.] ActiveCell.Interior.Color = vbGreen '---- Clean up. Set objSheet = Nothing End Sub
You will note that:
- You can include comments! Those are good for others, and for yourself in weeks/months/years to come when you have to look at the code again. And this becomes more important as the code (almost inevitably) becomes more complex.
- By rearranging the code, you don't need three copies of the Cells.Find statement.
Then open the code window for one of your "floor" worksheets. You should see "(General)" in the dropdown at upper left and "(Declarations)" in the upper right. Select "Worksheet" from the former, and VBE will automatically start the code for an event handler; it chooses "SelectionChanged" by default when you don't already have other event handlers. Code to place in this module should eventually look like this (although the order of the two procedures does not matter):
Option Explicit '==== WORKSHEET-SCOPE VARIABLES Private m_PriorDeskCell As Range Private m_PriorDeskColor As Long Public Sub CaptureCurrentStuff(ByRef iobjActiveCell As Range) '---- Create a worksheet-scope object reference to that cell; ' copy the properties that are to be retained. Set m_PriorDeskCell = iobjActiveCell m_PriorDeskColor = iobjActiveCell.Interior.Color End Sub Private Sub Worksheet_SelectionChange(ByVal Target As Range) '---- Clear the highlighting, if any, from the prior ' active range. If m_PriorDeskCell Is Nothing Then 'No action is needed. Else ' -- Reset the color. m_PriorDeskCell.Interior.Color = m_PriorDeskColor ' -- Destroy the object reference. Set m_PriorDeskCell = Nothing End If End Sub
Repeat as needed for each "floor" worksheet.
I am attaching a workbook with this code for you to experiment with.
Netrix650 << … when I click away from it >>
The Excel object model does not support just a Click event (it does support DoubleClick and RightClick events), so it appears that you should use the SelectionChange event of the "floor" worksheets. (So you will advance from writing macro code to writing event handler code, and get more experience with VBA objects.) Such code is also written using the Visual Basic Editor (VBE), which offers some additional object-oriented assistance, as you will see below.
If you were modeling just one floor, or otherwise were using just one "floor" worksheet, you could do handle this more simply. But to handle "green cells" on multiple spreadsheets at once…
Your FindDesk procedure needs some modifications, as here:
Sub FindDesk()
Dim deskNo As String
Dim objSheet As Worksheet
'---- Grab the user-specified desk identifier.
deskNo = ActiveCell.Value
'MsgBox deskNo
'---- Select the worksheet that should contain that desk identifier,
' based on a floor number encoded at its start.
' If the identifier is "not valid", warn the user and exit.
If Left(deskNo, 1) = 1 Then
Set objSheet = Sheets("First floor")
ElseIf Left(deskNo, 1) = 2 Then
Set objSheet = Sheets("Second floor")
ElseIf Left(deskNo, 1) = 4 Then
Set objSheet = Sheets("Fourth floor")
Else
Call MsgBox(deskNo & " is not a recognized identifier." _
, vbExclamation Or vbOKOnly)
Exit Sub
End If
objSheet.Select
'---- Locate the next cell (there probably should be just one) that
' contains the desk identifier.
' [I would expect an error handler to be enabled here, if not earlier,
' unless other code ensures that the deskNo will be found.]
Cells.Find(What:=deskNo, After:=ActiveCell, LookIn:=xlFormulas2, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Activate
'NEED CODE HERE TO REVERT CELL TO ORIGINAL BACKGROUND WHEN IT IS NOT THE ACTIVE CELL
' [This is probably not the place to do that. After all, doing that
' here would mean you would have to call this procedure again to clear
' the highlighting.
' However, this is the place to capture the cell's address or reference,
' and its about-to-be-changed color.]
Call CallByName(objSheet, "CaptureCurrentStuff", VbMethod, ActiveCell)
'---- Highlight that cell in green. [You can replace vbGreen with the
' RGB function for some lighter or mixed-color shade.]
ActiveCell.Interior.Color = vbGreen
'---- Clean up.
Set objSheet = Nothing
End Sub
You will note that:
- You can include comments! Those are good for others, and for yourself in weeks/months/years to come when you have to look at the code again. And this becomes more important as the code (almost inevitably) becomes more complex.
- By rearranging the code, you don't need three copies of the Cells.Find statement.
Then open the code window for one of your "floor" worksheets. You should see "(General)" in the dropdown at upper left and "(Declarations)" in the upper right. Select "Worksheet" from the former, and VBE will automatically start the code for an event handler; it chooses "SelectionChanged" by default when you don't already have other event handlers. Code to place in this module should eventually look like this (although the order of the two procedures does not matter):
Option Explicit
'==== WORKSHEET-SCOPE VARIABLES
Private m_PriorDeskCell As Range
Private m_PriorDeskColor As Long
Public Sub CaptureCurrentStuff(ByRef iobjActiveCell As Range)
'---- Create a worksheet-scope object reference to that cell;
' copy the properties that are to be retained.
Set m_PriorDeskCell = iobjActiveCell
m_PriorDeskColor = iobjActiveCell.Interior.Color
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'---- Clear the highlighting, if any, from the prior
' active range.
If m_PriorDeskCell Is Nothing Then
'No action is needed.
Else
' -- Reset the color.
m_PriorDeskCell.Interior.Color = m_PriorDeskColor
' -- Destroy the object reference.
Set m_PriorDeskCell = Nothing
End If
End Sub
Repeat as needed for each "floor" worksheet.
I am attaching a workbook with this code for you to experiment with.
- Netrix650Feb 07, 2023Copper ContributorWow !! Thank you SnowMan55 it does exactly what I asked for, and thank you for taking the time to explain each step - very much appreciated.
Consolidating the code down made perfect sense - if I'm honest the Event Handler code is still a bit "smoke and mirrors" 😄 but I'll get there !!
Thanks again