【问题标题】:Execute macro only if specific cell value changes仅在特定单元格值更改时执行宏
【发布时间】:2019-04-09 04:33:52
【问题描述】:

我在单元格 E2 中有一个简单的 countif 公式,它将检查特定文本。一旦它为真,它将执行一个宏,该宏会提示输入一个 msgbox。此代码工作正常,但是当对工作表进行任何其他更改时,将再次执行宏,即使单元格 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 

编辑:感谢下面的评论,将“旧代码”设置目标删除到相交线中的相同范围。但是,宏不再被触发。

【问题讨论】:

  • 删除Set Target = Range("E2")
  • 愚蠢的我,我将不同的代码混合在一起,现在变得一团糟。感谢您的提示,现在 intersect 找到了我手动更改的值。
  • 很可能它现在没有触发,因为代码已经半途而废,所以它还没有达到重新启用事件的地步,进入调试窗口(来自 VBE 的 ctrl-G并输入Application.EnableEvents = True 并按回车,这应该会为您解决问题。

标签: excel vba worksheet


【解决方案1】:

原来我把事情复杂化了。经过一些研究,我想要做的事情首先不适用于 Worksheet_Change,因为这是一个公式。所以,我只需要将我的代码移到 Worksheet_Calculate 上。不需要不必要的相交或任何东西,因为我的代码只需要确定单元格 E2 是否为真,这是由单元格公式确定的。反正其他都无所谓了。

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

【讨论】:

    【解决方案2】:

    真正的解决方案

    CountIf 公式的结果是整数 或错误。因此,您可能有一个 If 语句正在计算单元格 E2 中的 CountIf 公式。
    如果结果是 booleanTrueFalse),则使用不带引号的 TrueNOT "True")。
    您应该始终使用Option Explicit 来强制声明所有变量(指“a”)。
    在代码的开头使用常量,以便能够在仅在一个地方快速更改值(如有必要)。
    在您的回答中,如果 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
          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
    

    【讨论】:

      猜你喜欢
      • 2010-09-29
      • 1970-01-01
      • 2021-02-14
      • 1970-01-01
      • 1970-01-01
      • 2013-12-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多