如何克服Excel中的“堆栈不足空间错误”?

时间:2019-04-08 14:30:38

标签: excel vba

如果A3中的计数不等于6,我试图将数据从单元格A5清除到A10。我编写了一个“ If语句”,但是它给了我堆栈错误。我该如何克服这个错误

我尝试了一个“ if语句”,但它给了我错误。

Dim Count As Integer
Dim BundleDup As Integer
Dim duplicateall As Integer
Dim SAPError As Integer

Private Sub Worksheet_Change(ByVal Target As Range)
    Count = Range("A3").Value
    BundleDup = Range("B3").Value
    duplicateall = Range("C3").Value
    SAPError = Range("D3").Value

    If Target.Address = "$A$10" And Count = 6 And BundleDup = 0 And duplicateall = 0 And SAPError = 0 Then

        newHour = Hour(Now())
        newMinute = Minute(Now())
        newSecond = Second(Now()) + 3
        waitTime = TimeSerial(newHour, newMinute, newSecond)
        Application.Wait waitTime
        Call MoveData
    End If

    If Count <> 6 Then
        Call ClearData
    End If

End Sub

如果我不使用此代码,则代码工作正常

 If Count <> 6 Then
        Call ClearData
    End If

但是一旦我使用它并在A5到A10中输入值,它将清除数据,但会卡住并给我错误。

ClearData模块包含以下代码:

Sub ClearData()
'
' ClearData Macro
'

'
    Range("A5:A10").Select
    Range("A10").Activate
    Selection.ClearContents
    Range("A5").Select
End Sub

2 个答案:

答案 0 :(得分:1)

只需在Rory的注释周围添加一点-这里的问题是您在代码中创建了一个无限循环。

从高层次来看,这是正在发生的事情:

1. You change a value on your worksheet
2. The Worksheet_Change() code is called
3. This code then changes something on the same worksheet
4. This change causes the Worksheet_Change() code to run again
5. This code then changes something on the same worksheet
6. This change causes the Worksheet_Change() code to run again
7. This code then changes something on the same worksheet
8. This change causes the Worksheet_Change() code to run again
9.This code then changes something on the same worksheet

   (you get the picture...)

要解决此问题,您需要禁止在代码中调用任何其他事件:

Private Sub Worksheet_Change(ByVal Target As Range)

    Application.EnableEvents = False '// stop further events from firing

    Count = Range("A3").Value
    BundleDup = Range("B3").Value
    duplicateall = Range("C3").Value
    SAPError = Range("D3").Value

    If Target.Address = "$A$10" And Count = 6 And BundleDup = 0 And duplicateall = 0 And SAPError = 0 Then

        newHour = Hour(Now())
        newMinute = Minute(Now())
        newSecond = Second(Now()) + 3
        waitTime = TimeSerial(newHour, newMinute, newSecond)
        Application.Wait waitTime
        Call MoveData
    End If

    If Count <> 6 Then
        Call ClearData
    End If

    Application.EnableEvents = True '// re-enable events

End Sub

最后,如果您要更改代码中的应用程序级别设置-我会强烈建议您在代码中编写适当的错误处理程序,以在运行时还原所有此类设置错误。

答案 1 :(得分:1)

这是应对这种情况的方式:

    Public ClearingData As Boolean  'initializes natively to "False"

    Private Sub Worksheet_Change(ByVal Target As Range)
    If ClearingData Then Exit Sub 'stops the recursive loop
    ClearingData = True

    Count = Range("A3").Value
    BundleDup = Range("B3").Value
    duplicateall = Range("C3").Value
    SAPError = Range("D3").Value

    If Target.Address = "$A$10" And Count = 6 And BundleDup = 0 And duplicateall = 0 And SAPError = 0 Then

        newHour = Hour(Now())
        newMinute = Minute(Now())
        newSecond = Second(Now()) + 3
        waitTime = TimeSerial(newHour, newMinute, newSecond)
        Application.Wait waitTime
        Call MoveData
    End If

    If Count <> 6 Then
        Call ClearData 'Here's where the recursive loop gets created.
    End If

    ClearingData = False

    End Sub

这可防止递归循环开始,并且仍使事件保持启用状态。该代码完全处理了函数中的特定情况,避免了可能影响其他函数的意外结果。

如果“ MoveData”函数更改了单元格选择,并且调用了“ Worksheet_SelectionChange”事件,则禁用事件将阻止该事件被调用。通过使用上述逻辑,该事件仍将被调用。如果要防止从此函数中调用“ Worksheet_SelectionChange”,只需在“ Worksheet_SelectionChange”事件的开始处添加“ If ClearingData Then Exit Sub”行。

对不起,我在上面的评论中使用了“全球”一词,而不是“公共”。