Reputation: 67
I have a Sub that I would like to run whenever cells are updated to contain a certain value.
Right now I'm using code like the following:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
If Target.Cells.Count = 1 Then
If Target.Value = XYZ Then
my_sub a, b, c
End If
End If
End Sub
The issue right now is that the macro only fires when I edit these cells directly, not when changes in other cells force these cells to change.
Additionally, these cells are not well defined, so I can not hard code "when A5 changes", for example. I need this to fire every time any cell in my workbook is updated (manually or through formulas) to meet my condition.
Upvotes: 0
Views: 1312
Reputation: 55672
Calculate
event to check if the number of occurences changescode
Private Sub Worksheet_Calculate()
Dim StrIn As String
Static lngCnt As Long
Dim lngCnt2 As Long
StrIn = "apples"
lngCnt2 = Application.WorksheetFunction.CountIf(Range("rngValue"), StrIn)
If lngCnt2 <> lngCnt Then
lngCnt = lngCnt2
Call mysub
End If
End Sub
Upvotes: 1
Reputation: 1691
Provided your target is only a single cell with a formula that needs to be monitored, this will work:
Option Explicit
Dim tarVal As Variant
Private Sub Worksheet_Activate()
tarVal = ActiveSheet.Range("A1").Value ' change range parameter to the address of the target formula
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Dim tempVal As Variant
tempVal = ActiveSheet.Range("A1").Value
If tempVal <> tarVal Then
tarVal = tempVal
' your code here
MsgBox "The value of A1 has changed" ' for testing purposes only, delete later
End If
End Sub
Edit
The following code works for an entire range of cells, but only if automatic calculation is turned on. In case the monitored cells are non-contiguous, just use union statements when defining the target range. (The target range is A1:A10 in this example). This is under the assumption that only one of formulas in the target range can change its value at a time. If multiple target formulas can do that, then remove Exit for
in the Worksheet_Change
subroutine.
Option Explicit
Dim tarCellCount As Long
Dim tarRng As Range
Dim tarVals As Variant
Private Sub Worksheet_Activate()
Dim i As Long
Dim cll As Range
Set tarRng = ActiveSheet.Range("A1:A10") ' change range parameter to the addresses of the target formulas
tarCellCount = tarRng.Cells.count
ReDim tarVals(1 To tarCellCount) As Variant
For Each cll In tarRng
i = i + 1
tarVals(i) = cll.Value
Next cll
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Dim changeBool As Boolean
Dim i As Long
Dim cll As Range
Dim tempVal As Variant
For Each cll In tarRng
tempVal = cll.Value
i = i + 1
If tempVal <> tarVals(i) Then
tarVals(i) = tempVal
changeBool = True
Exit For
End If
Next cll
If changeBool Then
' your code here
MsgBox "The value of one of the cells in the target range has changed" ' for testing purposes only, delete later
End If
End Sub
Upvotes: 2
Reputation: 363
Target is a range that CAN contain more cells. This code should work for you.
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
For Each cell In Target.Cells
If cell.Value = XYZ Then
my_sub a, b, c
End If
Next cell
End Sub
Edit: I see that you want to fire that also when formula is updated defined value. It can be slow if you will check every cell, but really depends on the size of your file. Here is some code to give you idea how to do it.
Private Sub Workbook_SheetCalculate(ByVal sh As Object)
For Each cell In sh.Cells.SpecialCells(xlCellTypeFormulas).Cells
If cell.Value = XYZ Then
my_sub a, b, c
End If
Next cell
End Sub
Upvotes: -1