【问题标题】:Worksheet_change macro running multiple times in excel 2007Worksheet_change 宏在 excel 2007 中运行多次
【发布时间】:2015-08-18 05:48:05
【问题描述】:

我有几个工作表,我在其中使用宏进行一些计算。如果范围内的任何单元格发生更改,则应该运行此计算。

下面是运行的代码。

 Private Sub Worksheet_Change(ByVal Target As Range)
   ' Check if change is made to the correct range of cells.
   Dim Results As Variant

   'Defaults while sheet only used in Rotterdam
   mGravityUnit = UnitDensity
   mVolumeUnit = UnitCubicMetres
   mTempUnit = UnitCelcius

    With Application
        If Not (.Intersect(Target, Range("Grade1ROBTemp")) Is Nothing And .Intersect(Target, Range("Grade1ROBDensity")) Is Nothing And .Intersect(Target, Range("Grade1ROBVCF")) Is Nothing And .Intersect(Target, Range("Grade2ROBTemp")) Is Nothing And .Intersect(Target, Range("Grade2ROBDensity")) Is Nothing And .Intersect(Target, Range("Grade2ROBVCF")) Is Nothing And .Intersect(Target, Range("Grade3ROBTemp")) Is Nothing And .Intersect(Target, Range("Grade3ROBDensity")) Is Nothing And .Intersect(Target, Range("Grade3ROBVCF")) Is Nothing) Then
            ' Change in Volume Temp or Density
            Dim ThisRow As Integer, VCF As Double
            ThisRow = Target.Row
            If Not (Cells(ThisRow, 8) = "" Or Cells(ThisRow, 9) = "") Then
                WaitFor (0.05)
                Results = VCF_Calculation(Cells(ThisRow, 8), mTempUnit, Cells(ThisRow, 9), mGravityUnit, mVolumeUnit)
                Cells(ThisRow, 10) = Results
            Else
                Cells(ThisRow, 10) = ""
            End If
        End If
    End With
End Sub

此代码在一个工作表中运行良好,仅针对发生更改的行运行。

但在另一张表中,相同的代码会针对范围内的所有行运行,而不是针对单元格更改的那一行。因此,宏无法正常运行,因为它花费的时间超过了工作所需的时间。

显然,我应该在 excel 范围内设置一些属性,这将导致宏仅对更新的行运行,而不是对所有行运行。

编辑: 我想我定义的范围错误,这就是它一次又一次触发更改事件的原因。

禁用事件解决了这个问题。谢谢大家。

【问题讨论】:

  • 首先在 intersect 之后添加Application.EnableEvents = False,然后在退出子之前添加Application.EnableEvents = True。未能添加此关键代码将使子尝试在您更改工作表上的值后立即在其自身之上运行。
  • 让我试试这个。给我一点时间。
  • 我同意@Jeeped。此代码Cells(ThisRow, 10) = xxx 将重新触发Worksheet_Change 事件。
  • 谢谢。这样可行。虽然,我想知道为什么这在另一张纸上效果很好。也许,我定义了错误的范围。无论如何,我在所有工作表中添加了代码以确保它不会给出相同的错误。

标签: vba excel


【解决方案1】:

首先在相交之后添加Application.EnableEvents = False,然后在退出子之前添加Application.EnableEvents = True。未能添加此关键代码将使子尝试在您更改工作表上的值后立即在其自身之上运行。

使用Union method 将所有命名范围拼接在一起。

在你知道你将需要它们之前,甚至不要使变量变暗。

Private Sub Worksheet_Change(ByVal Target As Range)

    'only process if we are dealing with a single Target
    If Target.Count > 1 Then Exit Sub

    If Not Intersect(Target, Union(Range("Grade1ROBTemp"), Range("Grade1ROBDensity"), _
      Range("Grade1ROBVCF"), Range("Grade2ROBTemp"), Range("Grade2ROBDensity"), Range("Grade2ROBVCF"), _
      Range("Grade3ROBTemp"), Range("Grade3ROBDensity"), Range("Grade3ROBVCF"))) Is Nothing Then
        On Error GoTo bm_Safe_Exit
        Application.EnableEvents = False

        'Defaults while sheet only used in Rotterdam
        mGravityUnit = UnitDensity
        mVolumeUnit = UnitCubicMetres
        mTempUnit = UnitCelcius

        ' Change in Volume Temp or Density
        Dim ThisRow As Long, VCF As Double, Results As Variant
        ThisRow = Target.Row
        If CBool(Len(Cells(ThisRow, 8))) And CBool(Len(Cells(ThisRow, 9))) Then
            WaitFor (0.05)
            Results = VCF_Calculation(Cells(ThisRow, 8), mTempUnit, Cells(ThisRow, 9), mGravityUnit, mVolumeUnit)
            Cells(ThisRow, 10) = Results
        Else
            Cells(ThisRow, 10) = ""
        End If
    End If

bm_Safe_Exit:
    Application.EnableEvents = True
End Sub

仅当单个调用是目标时才处理您的代码。如果更改了多个单元格,则上述代码将不起作用。您将不得不使用For Each rng in INtersect(... 之类的东西。

【讨论】:

  • 谢谢。这比现有代码工作得更快。抱歉,这不是我的代码。我只是从现有工作表中复制了代码,只是在我的情况下它抛出了这个错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
  • 1970-01-01
  • 2010-11-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多