仅当特定单元格值更改时才执行宏

时间:2018-11-05 19:18:11

标签: excel vba worksheet

我在单元格E2中有一个简单的countif公式,该公式将检查特定的文本。一旦正确,它将执行一个宏,提示输入msgbox。这段代码可以正常工作,但是对工作表进行任何其他更改时,即使Cell E2的值没有更改,该宏也会再次执行。如果E2完全没有变化,如何停止宏进一步执行?

Sub Worksheet_Change(ByVal Target As Range)

If Not Intersect(Target, Range("E2")) Is Nothing Then
    If Target.Value = "True" Then
        Application.EnableEvents = False
        a = MsgBox("Test", vbYesNo, "Test")
        If a = vbYes Then
            Range("E3") = "003"
        Else
            Range("E3") = "001"
        End If

        Call ApplyMG
        Application.EnableEvents = True
    End If
End If
End Sub 

编辑:由于下面的注释,将“旧代码”设置目标移至了相交行中的相同范围。但是,宏不再被触发。

2 个答案:

答案 0 :(得分:1)

事实证明,我的工作过于复杂。经过一番研究后,我试图做的事情首先不会在Worksheet_Change上起作用,因为这是一个公式。因此,我只需要将代码移到Worksheet_Calculate即可。不需要不必要的相交或其他任何东西,因为我的代码仅需要确定单元格E2是否为True(由单元格公式确定)。没关系了。

Private Sub Worksheet_Calculate()
Dim trigger As Range
Set trigger = Range("E2")

If trigger.Value = "True" Then
    Application.EnableEvents = False
    a = MsgBox("Test", vbYesNo, "Test")
    If a = vbYes Then
        Range("E3") = "003"
    Else
        Range("E3") = "001"
    End If

    Call ApplyMG
    Application.EnableEvents = True
End If
End Sub

答案 1 :(得分:0)

一个真正的解决方案

CountIf 公式的结果是整数或错误。因此,您可能有一个 If 语句,该语句正在单元格E2中计算CountIf公式。
如果结果为布尔值TrueFalse,请使用不带引号的 True “ True”) )。
您应该始终使用Option Explicit来强制声明所有变量(指的是“ a”)。
在代码的开头使用 constants (常量),可以在需要的地方仅快速更改一个位置中的值。
在您的答案中,如果E2中的值为True,则无论代码值是否更改,代码始终一直在运行(计算工作表时)。
以下代码可能是使用过程内部的静态变量而不是过程外部选择的模块级变量blnCheck)编写的。 (应进行调查。)

Option Explicit

Private blnCheck As Boolean

Private Sub Worksheet_Calculate()

  Const cStrRangeCheck As String = "E2"
  Const cStrRangeWrite As String = "E3"
  Const cStrResultYes As String = "003"
  Const cSTrResultNo As String = "001"

  Dim Msg As Variant
  Dim blnTarget As Boolean

  If IsError(Range(cStrRangeCheck).Value) Then GoTo TargetHandler

  blnTarget = Range(cStrRangeCheck).Value

  If blnTarget = True Then
    If blnCheck = False Then
      blnCheck = True
      Application.EnableEvents = False
      Msg = MsgBox("Test", vbYesNo, "Test")
      If Msg = vbYes Then
          Range(cStrRangeWrite) = cStrResultYes
        Else
          Range(cStrRangeWrite) = cSTrResultNo
      End If
      Call ApplyMG
      Application.EnableEvents = True
    End If
   Else 'blnTarget = False
    If blnCheck = True Then
      blnCheck = False
    End If
  End If

ProcedureExit:

Exit Sub

TargetHandler:
  MsgBox "blnTarget has to be a boolean."
  GoTo ProcedureExit

End Sub