I'm very new to VBA. I have a cell in the worksheet that live updates a value. the Value changes about once every month. Is there a way for me to record the day that the value changed in an adjacent cell?
For example,
If the value in A1 changes from 5 to 6 today, I just want to record today's date in A2.
I don't really need to keep a record of previous changes.
Thank you so much!
If you are using a Bloomberg function in cell A1 like BDP() or BDH() or BDS(), then you could use the Worksheet_Calculate() event macro to detect changes in that cell.
In this example, I use cell A3 as a "memory" to avoid re-posting the date too often:
Private Sub Worksheet_Calculate()
Application.EnableEvents = False
If [A1] <> [A3] Then
[A3] = Range("A1").Value
[A2] = Date
MsgBox "Date recorded"
End If
Application.EnableEvents = True
End Sub
The Worksheet_Change() is being fired when something on the sheet changes its value, so add something like this to your Sheet-Codemodule:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$A$1" Then
Debug.Print "A1 has been changed!"
'do something
End If
End Sub
Update:
It seems you need the calculate event also as you're using a formula. you could try something like this:
Private Sub Worksheet_Calculate()
Application.EnableEvents = False
ActiveSheet.Calculate
DoEvents
With Range("A1")
.Value = .Value
DoEvents
End With
Application.EnableEvents = True
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$A$1" Then
Range("A2").Value = Date
End If
End Sub
You could use the Worksheet_SelectionChange event. I guess it depends on what else you're doing in the worksheet as to whether it would fire or not.
You'd have to compare the value in A1 against what was in A1 previously which would be stored in another cell.
Related
its me....again. I am currently trying to have a Macro trigger whenever a specific cell increases on a specific sheet.
After many attempts I have been able to get the Macro to trigger when the cell is changed (increasing or decreasing) but I cannot figure out a way to have this Macro trigger only when the specified cell increases in value.
I have tried to use simple Worksheet_Change with an If Then statement that calls the Macro when the cell value is changed. Again I can't get this to trigger only when the cell increases. Not sure it is possible or if I am even thinking about this is in the right way.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address "Range" Then
Call MyMacro
End If
End Sub
Thank you for any help in advance. This would be really neat and save alot of manual clicking around.
Here is the functioning Macro that I want to trigger when certain text is entered into a range.
Sub Auto_Print_Yellow_Caution()
Application.ScreenUpdating = False
Sheets("Saver").Shapes("Group 6").Copy
Sheets("Main").Select
ActiveCell.Offset(-1, 0).Select
ActiveSheet.Paste
ActiveCell.Select
Application.ScreenUpdating = True
End Sub
I already have my Workbook set up to track these words/phrases and return either a TRUE or FALSE value. If TRUE the associated Order Number is Printed into a Cell and a COUNTIFS formula is used to keep track of how many orders meet the TRUE condition. That number is then used to keep track of how many total of those orders there are. That works using the following
=IF(ISNUMBER(SEARCH("Completed",Main!G7)),TRUE)
-looks for specific word and returns TRUE
=IF(T3=TRUE,Main!A7,"")
-Returns order number
=IF(COUNTIF($U3:$U$200,"?*")<ROW(U3)-2,"",INDEX(U:U,SMALL(IF(U$2:U$200<>"",ROW(U$2:U$200)),ROWS(U$2:U3))))
-Sorts order numbers into list
=COUNTIF(T2:T135,TRUE)
-Counts number of orders
Hopefully this adds context to what I am trying to accomplish.
This will hopefully get you on the right track. As per your question it assumes this is required for a single cell only (and in this example code, that cell is B2). The trick is to store the new value, 'undo' the change, grab the old value, reverse the 'undo' by replacing the new value. Then you can test if the values are numbers and, if so, test if the new number is greater than the old number.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim newValue As Variant, oldValue As Variant
If Target Is Nothing Then Exit Sub
If Target.Cells.Count <> 1 Then Exit Sub
If Target.Column <> 2 Or Target.Row <> 2 Then Exit Sub ' example is using cell B2
Application.EnableEvents = False
newValue = Target.Value2
Application.Undo
oldValue = Target.Value2
Target.Value2 = newValue
Application.EnableEvents = True
If IsNumeric(oldValue) And IsNumeric(newValue) Then
If CDbl(newValue) > CDbl(oldValue) Then
Call MyMacro
End If
End If
End Sub
Here is some logic I can think of, you need to have a helper cell to store previous data and compare if it increased. In this sample my helper cell is B1 and the cell I want to track is A1
Private Sub Worksheet_Change(ByVal Target As Range)
Dim KCells As Range
Set KCells = Sheet10.Range("A1")' The variable KeyCells contains the cells that will
If Not Application.Intersect(KCells, Range(Target.Address)) Is Nothing Then 'cause an alert when they are changed.
If Sheet10.Range("B1").Value < Sheet10.Range("A1").Value Then
MsgBox "Replace this to call macro"
Sheet10.Range("B1").Value = Sheet10.Range("A1").Value 'this is to save the current data incase you change it later.
End If
End If
End Sub
I have a cell which i declared as active cell using developers tool in excel
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Range("C1").Value = ActiveCell.Value
End Sub
this cell is equals to the value of a drop down cell i created from data validation.
My Problem is cell C1 is not changing when i select a new value from the drop down
Here you go. When B1 is changed C1 is assigned the value of B1. It doesn't matter how the change was carried out, from the keyboard or by selection from a drop-down.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = Range("B1").Address Then
' prevent the coming change from causing a call of this procedure
Application.EnableEvents = False
Cells(1, "C").Value = Target.Value
Application.EnableEvents = True
End If
End Sub
I want MyMacro to run automatically when the cell value in A1 changes according to a vlookup formula. MyMacro copies a row then pastes it to a different section of the worksheet when a condition dependant on the value of A1 is met.
I have tried variations of Target.Address and the following, which have not worked:
Public Sub Worksheet_Calculate(ByVal Target As Range)
Static OldVal As Variant
If Range("A1").Value <> OldVal Then
OldVal = Range("A1").Value
If Not Intersect(Target(1), Range("C1401:I140")) Is Nothing Then
If Range("A1").Value < ActiveSheet.Range("A1").Value Then
Range("C140:I140").Value = Range("B55:H55").Value
ElseIf Range("B55").Value > ActiveSheet.Range("A1").Value Then
Range("C140:I140").Formula = ""
End If
End If
End If
End Sub
Public Sub MyMacro()
Worksheet_Calculate ([C140])
End Sub
With this, MyMacro only works when I manually hit Run Macro after each time A1 changes. How can I get this to be automatic?
Thanks.
If you want to do something when the value of your calculated Cell A1 changes then use the Worksheet_Change event on the relevant worksheet.
(Find the worksheet in the VBA editor and right-click to select "view code")
Sub Worksheet_Change(ByVal Target As Range)
If Not Application.Intersect(Range("$A$1"), Target) Is Nothing Then
... [call your change_routine]
end if
End Sub
I'm creating a report-styled sheet in Excel, and trying to get a timestamp to automatically be entered in cell "P4" if cell "I6" has a value of "Completed"
I've tried using =IF formulas, which worked, but I'm unable to toggle iterative calculation on the machines this sheet will be working on.
I'm fairly new to writing my own VBA, and I'm having some trouble getting my current code to work. Below is what I currently have, which isn't giving me any results.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As String
Set r = Cells("I6")
If r.Value Is Nothing Then Exit Sub
If r.Value <> "Completed" Then Exit Sub
If r.Offset(-2, 7).Value <> "" Then Exit Sub
Application.EnableEvents = False
r.Offset(-2, 7) = Now()
Application.EnableEvents = True
End If
End Sub
I expect the code to give me a current timestamp in Cell "P4" once the value "Completed" is entered into cell "I6", but nothing is showing up. How would I correct it in order to get the value based timestamps?
As this sub is called at every cell's change (and you may use it later for other cell-checks also), check by Intersect first, if "your" cell is affected.
The changed range is given as Target (which may be a single cell or a complete range, e. g. when you paste on it). If that is intersected with your monitored cell I6, you can go ...
Private Sub Worksheet_Change(ByVal Target As Range)
Dim RelevantArea As Range
Set RelevantArea = Intersect(Target, Me.Range("I6"))
If Not RelevantArea Is Nothing Then
If Target.Value = "Completed" Then
Application.EnableEvents = False
Me.Range("P4").Value = Now()
Application.EnableEvents = True
End If
End If
End Sub
Hope someone can answer us.
We want to do the following:
When a value is entered in A1, this value is added to the value of B1.
We then want the value of A1 too reset to 0, but keep the value of B1
Is this possible in excel?
On the worksheet's VBA private module (right-click the report tab and hit "View Code"), enter the following code:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Target.Address = Range("a1").Address Then
Range("b1") = Range("b1") + Range("a1")
Range("a1").ClearContents
End If
Application.EnableEvents = True
End Sub
Worksheet_Change is called whenever a change is made to the worksheet.
Application.EnableEvents=False prevents the code from running continuously (without it, the change to B1 would also call Worksheet_change).
This code assumes that the value in B1 is always numeric (or blank). If it may contain character text, then a check will need to be put in place to either reset its value or not do the increment.
Using simoco's suggestion:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim A1 As Range
Set A1 = Range("A1")
If Intersect(Target, A1) Is Nothing Then
Else
Application.EnableEvents = False
With A1
.Offset(0, 1) = .Offset(0, 1) + .Value
.ClearContents
End With
Application.EnableEvents = True
End If
End Sub