【发布时间】:2014-04-22 06:28:34
【问题描述】:
提前感谢您提供的任何明确信息。
在一个包含许多模块和工作表的 Excel 工作簿中,在 SHEET2 的 VBA 代码的底部,有这个子例程:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim TargetCells As Range
Set TargetCells = Range("B1000:B1029")
If Not Application.Intersect(TargetCells, Range(Target.Address)) Is Nothing Then
Call SpecificSubRoutine
End If
End Sub
我对这段代码的理解是,它会监视整个工作表的任何更改。如果 ANYTHING 发生更改,则工作表上的任何位置都会运行 If 语句。如果对工作表所做的任何更改发生在指定的 TargetCells 范围之外,则 If 语句将失败,但此 Sub 仍会在每次更改工作表时尝试验证 If 语句。
现在,您可能会猜到我的问题是堆栈溢出。 (运行时错误'28':堆栈空间不足)
每当Worksheet_Change Sub 运行时,如果对工作表的更改是在TargetCells 范围内进行的,它会调用填充单元格的SpecificSubRoutine,这会在每次SpecificSubRoutine 填充时触发Worksheet_Change Sub任何细胞。 (SpecificSubRoutine 也调用不同的模块,这些模块当然会填充单元格,这当然会触发Worksheet_Change Sub)
不太好。
此外,整个应用程序中的大多数子例程都包含在Application.ScreenUpdating = False / Application.ScreenUpdating = True 中,我错误地认为这会限制Worksheet_Change 在Application.ScreenUpdating = True 运行后立即被调用一次的次数。
重要提示: SpecificSubRoutine 和它调用的任何子例程都不会填充TargetCells 范围内的单元格。 我没那么暗。 ..
这是我的问题:
- 有没有办法缩小触发
Worksheet_ChangeSub 的范围,以便只有TargetCells范围内的更改才会触发它? (而不是更改工作表中的任何位置) - 有没有办法做我错误地认为
Application.ScreenUpdating会做的事情? (在一次批量更新中对工作表进行全部更改,而不是几乎每一步都触发更改) - 另外,作为一个额外的好奇心,有没有办法让
Worksheet_Change监视 2 个特定范围(而不是整个工作表?)知道如何做到这一点至关重要,并且可能会解决所有问题工作表。
我的直觉是将End 添加到SpecificSubRoutine 的最后一部分,或者添加到它调用的任何/所有子例程的末尾,但我只是不确定这会绕过@ 987654342@ 多次,因为Application.ScreenUpdating 不会像我想的那样批量更新。
想法?
【问题讨论】:
-
在
Worksheet_Change和最后Application.EnableEvents=True的开头添加Application.EnableEvents=False -
@simoco,这是一个很好的指针。谢谢!
标签: vba excel stack-overflow