I want to change the formatting of a cell if the value changes. I just need it to be shaded in.
I'm trying to use the following:
Private Sub Worksheet_Change(ByVal Target As Range)
Target.Interior.ColorIndex = 45
End Sub
However this is far too sensitive. For example if i delete a row, the entire row changes colour as technically it's a change. Even if I go into a cell, make no change and come out of it, it changes the formatting.
Is there anyway to edit the above so it only formats the cell's when the value has changed?
Thanks
I think you could use below code as a base for your further logic.
The idea is: we need to remember value before it is changed, so best to read it when some range is selected (since you are talking about single cell, I didn't consider ranges consisting of more cells). The value would be stored in global variable ValueOnEnter.
When the change is finally made, we compare values "before" and after", and if they differ, change the color.
Public ValueOnEnter As String
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Target.Value <> ValueOnEnter Then
Target.Interior.ColorIndex = 45
End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
ValueOnEnter = Target.Value
End Sub
Related
Does anyone know how I can add some code to my worksheet in VBA that evaluates a cell color only when the color is changed? So it would be similar to something like this
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$B$1" Then
Call Search_Batch_Docs
End If
End Sub
But would only trigger on a fill color change.
I have a sheet where I have color coded a column but I also have a column that contains a specific word that coincides with the color of the first column.
Excel doesn't have an event specifically for background color change. But checking the color of a single cell with each change shouldn't be unreasonable for most use-cases.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$B$1" And Target.Interior.color <> xlNone Then
Select Case Target.Interior.ColorIndex
Case 3
Target.offset(0, 1).Value = "Text if adjacent cell is red"
'And so on
End If
End Sub
EDIT: As per the comments below, this assumes that a VALUE in the targeted range has been changed, not only the formatting. If you require an event-based solution that is called more frequently, you could try Worksheet_SelectionChange to be called every time a new range becomes the active selection, but it will be less efficient.
If possible, it might be best to have a button to update values when pressed. And/or have it update when the worksheet is activated using Worksheet_Activate.
I have this certain code on a worksheet event cell change. It finds certain data that I have on a Worksheet when I type an id_parameter on cell A1.
After data is found, it writes it on this worksheet.
Now I'd like to run a different macro when I change the values on column C of the data.
I'm not able to find the proper procedure. Do_something() receives the value changed in column C. I hope I explained it clearly enough.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A1")) Is Nothing Then
Call Search_data
End If
'Data is written in B2:E10
If Not Intersect(Target, Range("C2:C10")) Is Nothing Then
Call Do_something(Target.Value)
End If
End Sub
The code you have posted works as intended. The issue is most probably due to Search_Data and or Do_Something.
You change the cell A1 which then changes all cells from B2:E10. Including the changed C2:C10 so make sure that the change_event cannot be triggered again by this.
Option Explicit
Public EventsDisabled As Boolean
Private Sub Worksheet_Change(ByVal Target As Range)
If Not EventsDisabled Then
EventsDisabled = True
If Not Intersect(Target, Range("A1")) Is Nothing Then
Call search_data
End If
'Data is written in B2:E10
If Not Intersect(Target, Range("C2:C10")) Is Nothing Then
Call do_something(Target.Value)
End If
End If
End Sub
The Public variable EventsDisabled will make sure that the change event runs when a user input is given but not if a Worksheet_Change event changes the worksheet. Otherwise you will run into all sorts of weird loopings which might be infinite or at least take a long time. Your issue will most probably also be related to this. Make sure that your Do_Something sub has the right input type. You should set a few breakpoints and open the local window under:
view>local window here you can see all variables and objects and their type. You can also type:
debug.print typename(Target.value)
into the direct window and then see what type you need to type into the Do_Something signature.
There is probably a better way to do what this however for science, I have a cell which goes up and down and at certain break points I would like to change the conditional formatting on other cells if a certain number is ever hit I want to change the color of the cell and when it changes I still want that cell to be conditionally formatted. Is this possible using a formula to conditional format?
Example
Let's say 100 is one of my breakpoints.
When I hit 100 on cell A1, I want to change B2 to a green fill
Now let's say A1 Changes from 100 to 125 for whatever reason. I still want to keep the fill on B2
When trying the below code:
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
If Range("A1").value = 100 Then Range("B1").ColorIndex = 4
End Sub
I get this error
Run-Time error '438':
Object doesn't support this property or method
You could start by placing this code in the relevant worksheet code pane (not in a standard module one):
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
If Target.Address = "$A$1" Then
If Target.Value = 100 Then Range("B1").Interior.ColorIndex = 4
End If
End Sub
You just have to change:
colorindex to the wanted color one
100 to the needed breakpoint
I have been trying to work this out myself for the last few days and caught myself in a bit of a one step forward three steps back cycle. I've been reluctant to bother you thinking this would have been answered somewhere else before now.
The idea is that I have a spreadsheet that has criteria in rows with separate entries in rows; in row 6 it is the status of each column entry, which when changed to "Completed" I would like the column to be hidden.
I've been floundering around with Worksheet_Change and been able to hide specific columns, but not the active column.
Any help offered would be much appreciated and I'm sorry if this has been covered elsewhere, but I've not been able to successfully apply any examples out there.
Thanks.
Whenever you have to work with worksheet_change events, you have to consider a cycle for it, due to user may delete multiple data at the same time or do a copy paste, if you only consider "Target" It would give a debugger error.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim ItemMultipleData As Range
For Each ItemMultipleData In Target 'handles multiple cells, paste, del, etc
'your code (instead of using "Target" change to ItemMultipleData. IE:
'If ItemMultipleData.Value = "Completed" Then
Next ItemMultipleData
End Sub
Here is a starting point. It only checks row # 6:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range
Set rng = Range("6:6")
If Intersect(Target, rng) Is Nothing Then Exit Sub
If Target.Count <> 1 Then Exit Sub
If Target.Value = "Completed" Then
Application.EnableEvents = False
Target.EntireColumn.Hidden = True
Application.EnableEvents = True
End If
End Sub
EDIT#1:
This approach assumes that only one cell at a time is being changed........that makes it easy to "find the active cell"
I have a worksheet with many dependant dropdowns that are liable to having invalid data if the initial drop down is altered. I would like a simple auto-macro that would automatically run the "circle invalid data" command every time a cell change within a specified range (D8:T800) is detected.
It sounds fairly straightforward but I am not sure how to do this.
Question - as this macro will run every single time a cell is amended would this macro slow down the worksheet?
EDIT:
Also: as this might be slow,is there a way we can run this command over a selected range?
Your thoughts thanks.
Try this
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("D8:T800")) Is Nothing Then
Me.CircleInvalid
End If
End Sub
Note that CircleInvalid applies to the whole sheet, so while this code only triggers when a cell inside D8:T800 changes, all invalid cells on the sheet will be circled
Try placing this code inside your Worksheet:
Private Sub Worksheet_Change(ByVal Target As Range)
' Check target range has changed
If (Not Intersect(Target, Range("D8:T800")) Is Nothing) Then
' Prevent recusrive looping
Application.EnableEvents = False
' Refresh validation circles
Target.Worksheet.CircleInvalid
Application.EnableEvents = True
End If
End Sub
Note that this will NOT work if the values in those cells change due to a calculation from outside the specified range.
Also, the CircleInvalid method applies to the whole worksheet.
You could try editing the code in the conditional to 'do something' if the Target is validated — this would result in you changing the format of invalid cells instead of having the red circles around them.
**PSEUDO-CODE**
For each cell in Target.Range
cell.colour = bright red
Next cell