在单步执行代码并正常运行时,Excel/VBA的行为不同

在单步执行代码并正常运行时,Excel/VBA的行为不同,excel,vba,Excel,Vba,我有VBA代码,其中包括函数工作表\u Calculate()和工作表\u Change(ByVal Target As Range),因为我想在重新计算时以及修改工作表中的某些特定单元格时更新某些单元格。这两个子例程调用完全相同的子例程。但是,其中一个可以正常工作(工作表\u更改),另一个不能正常工作(工作表\u计算),即使它们都调用完全相同的函数 我采取的下一步是在重新计算时我认为出错的地方设置断点,令我惊讶的是,Worksheet\u Calculate()执行的代码这次工作正常(当使用断

我有VBA代码,其中包括函数
工作表\u Calculate()
工作表\u Change(ByVal Target As Range)
,因为我想在重新计算时以及修改工作表中的某些特定单元格时更新某些单元格。这两个子例程调用完全相同的子例程。但是,其中一个可以正常工作(工作表\u更改),另一个不能正常工作(工作表\u计算),即使它们都调用完全相同的函数

我采取的下一步是在重新计算时我认为出错的地方设置断点,令我惊讶的是,
Worksheet\u Calculate()
执行的代码这次工作正常(当使用断点逐步遍历代码时,等等)。另外,即使在正常模式下(不在调试模式下),它也会在局部正常工作,但这是非常随机的。我不知道是什么原因造成的。下面是我的SUB的缩写版本(
MakeVisible
UpdateBaseline
UpdateDerivative1
…都是我后来定义的子程序):

在花了更多的时间进行调试之后,我认为存在一些争用条件,因为
UpdateBaseline
UpdateDrivative1
等中的代码实际上是在调整和移动一些形状对象(如星形、直线连接器等)这些被移动到错误的地方,即使我用来定位它们的变量似乎有正确的值。我的直觉告诉我,移动形状或改变它们的属性需要一些计算,这可能会导致一些竞争条件,但这只是一个猜测,可能完全无关


谢谢大家!

你可以试试这样的东西

Dim ignoreEvents As Boolean 

Private Sub Worksheet_Calculate()

    If ignoreEvents = True Then Exit Sub
    ignoreEvents = True

    ' your code here 

    ignoreEvents = False
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)

    If ignoreEvents = True Then Exit Sub
    ignoreEvents = True

    ' your code here 

    ignoreEvents = False
End Sub

多亏了@Slai,我才能够识别出这个问题。该错误确实是由当前活动工作表上的代码依赖性引起的,但在我为特定单元格指定工作表后,该错误没有得到修复(我将
[F4]
更改为
[Main!F4]
以及所有其他出现的错误)我仍然无法找出问题所在,因为我确保我的所有代码都与
[Main!]
Sheets(“Main”).Range(“”)
)一起工作,这将使对当前活动工作表的依赖性消失。但是,我添加了代码,使当前活动的工作表在触发
工作表\u Calculate()
时返回到“Main”,这导致了正确的行为。我添加的代码是
工作表(“Main”)。在
工作表的第一行激活
\u Calculate()


谢谢大家!

嗨,斯莱,谢谢你的回答。然而,这里的问题不是同一代码是否执行两次。我尝试将其添加到代码中,但行为完全相同。在调试模式下的行为与在代码中没有任何更改的正常模式下的行为不同,我已经多次这样做了,我不知道为什么。我在调试器中也使用了变量监视器,当从
工作表\u Change()
工作表\u Calculate()
调用子例程时,变量显示的值完全相同。谢谢我的另一个猜测是,您的一些代码可能依赖于当前选择。例如,
[F4]
可以根据激活/选择的工作表返回不同的值,但是
[Main!F4]
会更具体一些。
Dim ignoreEvents As Boolean 

Private Sub Worksheet_Calculate()

    If ignoreEvents = True Then Exit Sub
    ignoreEvents = True

    ' your code here 

    ignoreEvents = False
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)

    If ignoreEvents = True Then Exit Sub
    ignoreEvents = True

    ' your code here 

    ignoreEvents = False
End Sub