MS Excel VBA,堆栈外 space 和 Run-time 错误 '-2147417848 (800 10 108)':object 的方法 'Value' 'Range'失败

MS Excel VBA, Out of stack space and Run-time error '-2147417848 (800 10 108)': Method 'Value' of object 'Range' failed

当我使用 Worksheet_Change 和 Target 时,这两个问题不断出现。当我删除我认为 Target 所指的单元格之一的内容时,就会发生这种情况。我会把我的代码给看一下,它很简单:(PS,对VBA来说比较新,任何提示都会很棒!)

Private Sub Worksheet_Change(ByVal Target As Range)

'## Determine if change to cell Q6
If Target.Cells.count > 1 Then Exit Sub

If Target = Range("Q6") Then
    'Determine if the 1 is contained within cell Q6
    vRangeValue = Range("Q6").Value
    vStringValue = 1
    Application.EnableEvents = False

        'Paste value in R6
    If vRangeValue = vStringValue Then
        Range("R6").Value = 1
    End If

End If

'Remove 1 from R6
Range("R6").Value = 0
Range("R7").Value = 1
Application.EnableEvents = True

End Sub

当我第一次打开 sheet 并在 Q6 中输入 1 时,代码会执行我想要的操作(它会在 R6 中输入 1,然后快速将其切换回 0)。它还将 1 放入 R7 中,因为它运行得如此之快以至于我想要检查一下。但是,如果我删除 sheet 中任何单元格的内容(据我所知),我就会遇到标题中指定的两个错误之一。 我试过谷歌搜索,但我发现的所有示例都太具体而无法理解,所以我想我会在这里咨询。感谢您的帮助,如果我做了一些愚蠢的事情,我深表歉意!

这里有几个问题。

首先,您 运行 出栈 space 因为 Worksheet_Change 事件正在更改工作表,这会触发 Worksheet_Change 事件,从而更改工作表,这会触发 Worksheet_Change 事件,这...你明白了。

处理此问题的一种方法是添加一个重新进入标志,以防止事件处理程序递归。另一种是(如您所试)关闭事件,但见下文...我个人的偏好是使用重新进入标志,这样我就不会干扰我真正关心的其他事件。

其次,Range 的默认 属性 是 Value。这意味着这里的 "test"...

If Target = Range("Q6") Then

...正在比较 单元格内容 。它测试的是Range("Q6")中的Value赋值给Target是否是True。但在这一点上没关系,因为事件处理程序在 Application.EnableEvents = False 低于代码中的那一行时触发。

这部分做了一堆多余的工作,可以浓缩成一个简单的比较和赋值:

vRangeValue = Range("Q6").Value
vStringValue = 1
'...
If vRangeValue = vStringValue Then
Range("R6").Value = 1
End If

我会做更多这样的事情:

Private Changing As Boolean     'Module level scope

Private Sub Worksheet_Change(ByVal Target As Range)
    If Changing Or Target.Cells.Count > 1 _
    Or Application.Intersect(Target, Range("Q6")) Is Nothing Then Exit Sub

    Changing = True
    If Target.Value = 1 Then
        Range("R6").Value = 1
    End If

    'Range("R6").Value = 0  '<--No clue why you do this.
    Range("R7").Value = 1
    Changing = False
End Sub