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


91

每当特定单元格中的值更改时,如何自动执行Excel宏?

现在,我的工作代码是:

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

"H5"被监视的特定单元格在哪里Macro,宏的名称。

有没有更好的办法?


FormulaDesk中的RunMacroWhenValueChanges UDF是否满足您的要求?Formuladesk.com
Gareth Hayter

Answers:


106

您的代码看起来不错。

但是请小心,因为对的调用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

希望这可以帮助...


4
如果将单元格H5从另一个工作表更改,sheet2 该功能将不起作用。请帮助。
dhpratik

2
对于任何来自google搜索的人,请确保将此代码粘贴到vba中的工作表中,而不是像我这样的模块中。看看stackoverflow.com/questions/15337008/…–
hammythepig

Application.ActiveSheet.Range(“ H5”)。==> target.parent.range( “H5”)是更安全
皮埃尔

1
@WillEdiger每当您未明确指定工作表引用时,Excel都会假定,ActiveSheet而当您未明确指定正在使用的Excel时,Excel将假定Application
Scott Marcus

1
需要注意的是,在工作表中的代码模块(这是其中Worksheet_Change事件必须位于),不合格的Range没有默认ActiveSheet而是指包含此代码的片材。因此,此答案中的代码实际上与问题中的代码相同。(注意:回溯到2009年,当编写此答案时,它可能有所不同,但我可以肯定不是。)
YowE3K

7

处理Worksheet_Change事件或Workbook_SheetChange事件。

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


谢谢,它有效。我用来检查范围Target.Address = Range("H5").Address。有更容易的方法吗?
namin,

替代方法:Not (Intersect(Target, Range("H5")) Is Nothing) 。这是你会怎么做的吗?
namin,

2
Target.Address = Range("H5").Address如果您的单元格只是更改范围的一部分,则第一个注释()将不起作用。第二条评论仍然遭受Mike Rosenblum描述的问题。
蚂蚁

5

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

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

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

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

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

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

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

Application.EnableEvents = False

5)呼叫您的巨集

Call YourMacroName

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

Application.EnableEvents = True

7)结束If块和Sub:

    End If
End Sub

整个代码:

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Me.Range("B3")) Is Nothing Then
        Application.EnableEvents = False
        Call UpdateAndViewOnly
        Application.EnableEvents = True
    End If
End Sub

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


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

与一个单元格相同。您既可以将范围设置为一个单元格,也可以将范围设置为连续单元格,甚至可以将分散的单元格设置(全部用逗号分隔)。
Shai Alon 2015年

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

1
由于某种原因,我无法使它正常工作。当我告诉代码在VBA中运行时,它弹出一个弹出菜单并询问我是否要运行宏而不是自动运行宏?
David Van der Vieren
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.