在单元格更改上自动执行Excel宏

时间:2009-01-03 17:33:22

标签: excel vba excel-vba automation

每当特定单元格中的值发生变化时,如何自动执行Excel宏?

现在,我的工作代码是:

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Range("H5")) Is Nothing Then Macro
End Sub

其中"H5"是受监控的特定单元格,Macro是宏的名称。

有更好的方法吗?

5 个答案:

答案 0 :(得分:105)

你的代码看起来很不错。

但请注意,Range("H5")的来电是Application.Range("H5")的快捷命令,相当于Application.ActiveSheet.Range("H5")。如果唯一的更改是用户更改(这是最典型的),这可能没问题,但是当工作表的单元格值不是通过程序化更改的活动工作表时,可能会更改,例如, VBA。

考虑到这一点,我会使用Target.Worksheet.Range("H5")

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Target.Worksheet.Range("H5")) Is Nothing Then Macro
End Sub

或者您可以使用Me.Range("H5"),如果事件处理程序位于相关工作表的代码页上(通常是):

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Me.Range("H5")) Is Nothing Then Macro
End Sub

希望这会有所帮助......

答案 1 :(得分:7)

处理Worksheet_Change事件或Workbook_SheetChange事件。

事件处理程序采用参数“Target As Range”,因此您可以检查正在更改的范围是否包含您感兴趣的单元格。

答案 2 :(得分:3)

我更喜欢这种方式,不是使用单元格而是使用范围

    Dim cell_to_test As Range, cells_changed As Range

    Set cells_changed = Target(1, 1)
    Set cell_to_test = Range( RANGE_OF_CELLS_TO_DETECT )

    If Not Intersect(cells_changed, cell_to_test) Is Nothing Then 
       Macro
    End If

答案 3 :(得分:2)

在真正弄乱了事件触发因素之后,我花了很多时间研究此问题并学习了它们的工作原理。由于有太多分散的信息,因此我决定将我发现的全部工作共享在一个地方,如下:

1)打开VBA编辑器,在VBA项目(YourWorkBookName.xlsm)下,打开Microsoft Excel对象,然后选择与更改事件相关的工作表。

2)默认代码视图为“常规”。从顶部中间的下拉列表中,选择“工作表”。

3)Private Sub Worksheet_SelectionChange已经存在,应该保留,不理会。从上方复制/粘贴Mike Rosenblum的代码,然后将.Range引用更改为要监视其更改的单元格(在我的情况下为B3)。但是,请不要放置宏(我在“然后”之后删除了“宏”一词):

def decimal_value(d: Double, p: Integer) : 
  Double = {
   if (d >= 0) {
     BigDecimal.(d).setScale(p, BigDecimal.RoundingMode.HALF_UP).toDouble
   }
   else
     d
}

或从左上角的下拉列表中,选择“更改”,然后在“私人字幕”和“结束字幕”之间的空格中粘贴Private Sub Worksheet_Change(ByVal Target As Range) If Not Intersect(Target, Me.Range("H5")) Is Nothing Then End Sub

4)在“然后”之后的行上关闭事件,以便在您调用宏时,它不会触发事件并尝试在永无止境的循环中再次运行此Worksheet_Change,这会使Excel崩溃和/或以其他方式使一切混乱:

If Not Intersect(Target, Me.Range("H5")) Is Nothing Then

5)调用您的宏

Application.EnableEvents = False

6)重新打开事件,以便下次更改(以及任何/所有其他事件)触发:

Call YourMacroName

7)结束If块和Sub:

Application.EnableEvents = True

整个代码:

    End If
End Sub

这将打开/关闭事件从模块中移出,这会产生问题,并且只需让更改触发,关闭事件,运行宏并重新打开事件即可。

答案 4 :(得分:0)

我有一个链接到在线库存数据库并经常更新的单元格。我想在更新单元格值时触发宏。

我认为这类似于程序或任何外部数据更新的单元格值更改,但上面的示例在某种程度上对我不起作用。我认为问题是因为没有触发excel内部事件,但这就是我的猜测。

我做了以下,

Private Sub Worksheet_Change(ByVal Target As Range) 
  If Not Intersect(Target, Target.Worksheets("Symbols").Range("$C$3")) Is Nothing Then
   'Run Macro
End Sub