首页 > 解决方案 > 单元格值更改时自动执行 VBA 宏

问题描述

我有一个工作表(sheet1),其中包含一个A1带有公式的单元格='sheet2'!D10。我想在每次单元格更改时运行一个宏A1sheet1由于 中的更改D10sheet2sheet2正在流式传输财务数据。

因为是值的变化,Worksheet_Change不会触发事件。我似乎也无法找到解决方案Worksheet_Calculate

在我的研究中,这里提供了我能找到的最接近的解决方案,但我未能成功实施。

标签: excelvba

解决方案


您将不得不使用 Worksheet_Calculate。目前尚不清楚“流”是否会触发 Sheet2 中的 Worksheet_Calculate,但如果您将计算设置为自动,Sheet1 中的链接单元格肯定会触发该工作表的私有代码表中的 Worksheet_Calculate。

您需要一个变量来保存 Sheet1!A1 的先前值,该变量可以与 Sheet1!A1 的当前值进行比较。有些人更喜欢使用在公共模块的声明区域中声明的公共变量;我更喜欢在 Sheet1 的 Worksheet_Calculate 本身中使用静态变量。

微软文档

通常,一旦过程停止,过程中的局部变量就会不复存在。静态变量继续存在并保留其最新值。下次您的代码调用该过程时,该变量不会重新初始化,它仍然保存您分配给它的最新值。静态变量在定义它的类或模块的生命周期内继续存在。

第一个问题是为静态变量播种以供首次使用。使用 IsEmpty 测试时从未给出值报告 True 的变体类型变量,因此当第一次打开工作簿时,第一个计算周期将简单地将 Sheet1!A1 的值记录到静态变量中。任何未来的计算周期都会将 Sheet1!A1 中的值与静态 var 中保存的值进行比较,如果它们不同,则外部子过程(根据您的问题的叙述“...运行宏...” )将是运行,Sheet1!A1 的新值将存储在静态变量中。这样,Sheet1!A1 中的公式返回的值的任何更改都将强制执行计算周期,因此工作表的 Worksheet_Calculate 事件子过程将依次运行您的外部子过程。

在 Sheet1 的私有代码表中

Option Explicit

Private Sub Worksheet_Calculate()

    Static s2d10 As Variant

    If IsEmpty(s2d10) Then
        'load static var with expected value
        s2d10 = Cells(1, "A").Value2
    ElseIf s2d10 <> Cells(1, "A").Value2 Then
        'run sub procedure here
        '... run a macro ...'

        'load A1's current value into the static var
        s2d10 = Cells(1, "A").Value2
    End If

End Sub

推荐阅读