2016-07-25 17 views
0

Diese beiden Probleme tauchen immer auf, wenn ich Worksheet_Change und Target verwende. Das passiert, wenn ich den Inhalt einer der Zellen lösche, auf die sich Target bezieht. Ich werde meinen Code übergeben zu schauen, es ist ganz einfach: (PS, relativ neu in VBA, wäre alle Tipps groß!)MS Excel VBA, nicht im Stapelspeicher und Laufzeitfehler '-2147417848 (800 10 108)': Methode 'Wert' des Objekts 'Bereich' fehlgeschlagen

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 

Der Code tut, was ich will, wenn ich zum ersten Mal das Blatt öffnen und Typ 1 in Q6 (Es setzt eine 1 in R6 und schaltet dann schnell wieder auf 0 zurück). Es setzt auch 1 in R7, weil es so schnell geht, dass ich einen Check wollte. Aber wenn ich den Inhalt von Zellen in meinem Blatt lösche (soweit ich das beurteilen kann), habe ich einen der beiden im Titel angegebenen Fehler erhalten. Ich habe versucht zu googeln, aber alle Beispiele, die ich gefunden habe, sind zu spezifisch, um zu verstehen, also dachte ich, ich würde mich hier beraten. Danke für jede Hilfe, und tut mir leid, wenn ich etwas Dummes getan habe!

Antwort

2

Paar Probleme hier.

Zuerst Sie sind aus Stapelspeicher ausgeführt wird, weil das Worksheet_Change Ereignis das Arbeitsblatt ändert, die die Worksheet_Change Ereignis ausgelöst, die das Arbeitsblatt ändert, die die Worksheet_Change Ereignis ausgelöst, die ... Sie erhalten den Punkt.

Eine Möglichkeit, dies zu behandeln, ist das Hinzufügen eines Re-Entry-Flags, das verhindert, dass der Ereignishandler rekursiv wird. Der andere ist (wie Sie es versucht haben), Ereignisse abzuschalten, aber siehe unten ... Meine persönliche Präferenz ist es, eine Wiedereintrittsflagge zu verwenden, damit ich mich nicht in andere Ereignisse einmische, die mir wirklich wichtig sind.

Zweitens ist die Standardeigenschaft von RangeValue. Das heißt, die "Test" hier ...

If Target = Range("Q6") Then 

... vergleicht die Zellinhalte. Was es testet ist, ob die die Value in Range("Q6") zu Target zu True zuweist. Aber an dieser Stelle spielt es keine Rolle, da der Ereignishandler ausgelöst wird, dass Application.EnableEvents = False unter dieser Zeile in Ihrem Code ist.

Dieser Abschnitt hat eine Reihe von überflüssige Arbeit und kann in einem einfachen Vergleich und Zuweisung kondensiert werden:

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

ich etwas tun würde mehr wie folgt aus:

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