Excel命名范围更改事件

时间:2016-07-19 07:29:17

标签: vba excel-vba excel

我希望监控多个命名范围内的更改,这些范围的值根据公式而非用户输入而变化,因此range.Change += new DocEvents_ChangeEventHandler((Range Target) => { // do something }); 事件对我不起作用。

是否可以在VBA中执行以下C#代码的等效操作?

UIView's

2 个答案:

答案 0 :(得分:0)

您可以使用Name.Comment属性存储旧值。

Private Sub Workbook_SheetCalculate(ByVal Sh As Object)
    With ThisWorkbook
        If .Names("SumOfNumbers").Comment <> Range("SumOfNumbers").Value Then
            Debug.Print "SumOfNumbers has changed", .Names("SumOfNumbers").Comment, Range("SumOfNumbers").Value
            .Names("SumOfNumbers").Comment = Range("SumOfNumbers").Value
        End If

        If .Names("CountOfNumbers").Comment <> Range("CountOfNumbers").Value Then
            Debug.Print "CountOfNumbers has changed", .Names("CountOfNumbers").Comment, Range("CountOfNumbers").Value
            .Names("CountOfNumbers").Comment = Range("CountOfNumbers").Value
        End If

    End With
End Sub

enter image description here

答案 1 :(得分:0)

您可以创建自己的名称处理程序,在评估值更改时引发事件。

概述说,您可以使用以下代码插入新课程(我称之为NamesHandler):

Option Explicit

Public Event ValueChanged(sender As Name)
Private WithEvents mApp As Application
Private mOldValues As Collection

Private Sub mApp_AfterCalculate()
    Dim n As Name
    Dim oldVal As Variant
    Dim newVal As Variant

    For Each n In ThisWorkbook.Names
        oldVal = Empty
        On Error Resume Next
        oldVal = mOldValues(n.Name)
        On Error GoTo 0
        If Not IsEmpty(oldVal) Then
            newVal = Evaluate(n.Value)
            If newVal <> oldVal Then
                mOldValues.Remove n.Name
                mOldValues.Add newVal, n.Name
                RaiseEvent ValueChanged(n)
            End If
        End If
    Next
End Sub

Private Sub Class_Initialize()
    Dim n As Name
    Dim oldVal As Variant

    Set mApp = Application
    Set mOldValues = New Collection

    For Each n In ThisWorkbook.Names
        oldVal = Evaluate(n.Value)
        mOldValues.Add oldVal, n.Name
    Next
End Sub

然后,您可以在工作簿代码中使用该事件:

Private WithEvents mNamesHandler As NamesHandler

Private Sub mNamesHandler_ValueChanged(sender As Name)
    Debug.Print sender.Name
End Sub

Private Sub Workbook_Open()
    Set mNamesHandler = New NamesHandler
End Sub