每当更新单元格值时,如何触发Excel VBA宏?

时间:2016-08-18 18:28:37

标签: excel vba excel-vba

每当单元格更新为包含某个值时,我都会运行一个Sub。

现在我正在使用以下代码:

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

现在的问题是宏仅在我直接编辑这些单元格时触发,而不是在其他单元格中的更改强制更改这些单元格时触发。

此外,这些单元格没有很好地定义,所以我不能硬编码“当A5改变时”,例如。每次我的工作簿中的任何单元格更新(手动或通过公式)以满足我的条件时,我都需要激活它。

3 个答案:

答案 0 :(得分:2)

如果您的目标只是一个需要监控公式的单个单元格,则可以使用:

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

修改

以下代码适用于整个单元格范围,但仅限于启用自动计算时。如果受监视的单元格是非连续的,则在定义目标范围时只使用union语句。 (在此示例中,目标范围是A1:A10)。这是假设目标范围中只有一个公式可以一次改变其值。如果多个目标公式可以执行该操作,则删除Exit for子例程中的Worksheet_Change

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

答案 1 :(得分:1)

  1. 将要跟踪的单元格添加到命名公式(命名范围)。我使用了 rngValue
  2. 使用静态变量跟踪要在此范围内跟踪的值的次数
  3. 使用Calculate事件检查出现次数是否发生变化
  4. 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
    

答案 2 :(得分:-1)

目标是一个可以包含更多单元格的范围。此代码应该适合您。

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

编辑:我看到你想在公式更新定义值时触发它。如果要检查每个单元格,它可能会很慢,但实际上取决于文件的大小。这里有一些代码可以帮助您了解如何操作。

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