PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Hilfe bei VB Script, dauernte endlosschleifen


JasonX
2009-09-23, 13:55:35
Brauche bitte Hilfe bei folgendem Code:





Private Sub Worksheet_Change(ByVal Target As Range)

Tabelle1.Application.EnableEvents = False
Dim i As Byte

For i = 2 To 10 Step 1


Tabelle1.Range("B" & i).Activate

If ActiveCell.Text = "" Then

Exit Sub
Else

If ActiveCell.Text < 8.6 Then
Tabelle1.Range("C" & i).Value = 6

Else
If ActiveCell.Text >= 8.6 And ActiveCell.Text <= 8.8 Then
Tabelle1.Range("C" & i).Value = 5

Else
If ActiveCell.Text >= 8.8 And ActiveCell.Text <= 9.1 Then
Tabelle1.Range("C" & i).Value = 4

Else
If ActiveCell.Text >= 9.2 And ActiveCell.Text <= 9.7 Then
Tabelle1.Range("C" & i).Value = 3

Else
If ActiveCell.Text >= 9.8 And ActiveCell.Text <= 10 Then
Tabelle1.Range("C" & i).Value = 2

Else
If ActiveCell.Text >= 10.1 And ActiveCell.Text <= 10.3 Then
Tabelle1.Range("C" & i).Value = 1

Else
If ActiveCell.Text > 10.3 Then
Tabelle1.Range("C" & i).Value = 0
End If
End If
End If
End If
End If
End If
End If
End If
Tabelle1.aktivieren
Next i

End Sub


Public Function aktivieren()
Tabelle1.Application.EnableEvents = False
End Function






Das Problem ist, der Soll B2 prüfen, den passenden Wert in C2 wiedergeben, je nachdem welche Kriterien einstimmig sind.

z.B. B2 steht: 5,8
dann steht in C2 6

Und das wollte ich in der kompletten Spalte machen.
Nur immer wenn ich den Code ausführe macht er mir eine Endlosschleife, anstatt es mir einzeln abzufragen.

Findet da einer das Problem warum er mir immer und immerwieder das ganze in einer Endlosschleife macht und nicht von Zelle zu Zelle abwartet?

Danke im vorraus

Jason

Monger
2009-09-23, 15:11:08
Von den vielen If-Elses kriegt man ja Kopfschmerzen. Ist das VB.NET? Sieht eigentlich danach aus. Wenn du kannst, schreib es um - bei so vielen Schachtelungen übersieht man gerne mal was


Private Sub Worksheet_Change(ByVal Target As Range)

Tabelle1.Application.EnableEvents = False
Dim i As Byte

For i = 2 To 10 Step 1


Tabelle1.Range("B" & i).Activate

If String.IsNullOrEmpty(ActiveCell.Text) then Return
Dim Value as Integer
Select Case Double.Parse(ActiveCell.Text)
Case Is > 10.3 : Value = 0
Case Is > 10 : Value = 1
Case Is > 9.7 : Value = 2
Case Is > 9.1 : Value = 3
Case Is > 8,8 : Value = 4
case Is > 8.6 : Value = 5
Case Else : Value = 6
End Select

Tabelle1.Range("C" & i).Value = Value

Tabelle1.aktivieren
Next i

End Sub

Mir ist jetzt auch selber beim umschreiben schon aufgefallen, dass die Zahlen so nicht stimmen können. Manche Zahlenbereiche überlappen sich bei dir, andere haben zwischendrin Lücken. Ich vermute mal, das ist nicht beabsichtigt.

JasonX
2009-09-23, 15:20:40
Ja, erm sorry,

hab vergessen anzugeben das das VB aus Excel ist :redface:


Kennt wohl deshalb nicht :

If String.IsNullOrEmpty(ActiveCell.Text) then Return
...
Select Case Double.Parse(ActiveCell.Text)


Kanns nicht kompilieren.

MfG

Jason

Monger
2009-09-23, 15:38:15
Wenns nur das ist, dann schreibs halt wieder so um dass:


If ActiveCell.Text = "" Then Return

Select Case ActiveCell.Text
' etc etc. ...
End Select


Wo deine Endlosschleife herkommt, ist mir allerdings so oder so schleierhaft. Das dürfte eigentlich nicht passieren.

JasonX
2009-09-23, 16:22:40
Ok, vielleicht liegts noch daran

Laufzeitfehler 3
Return ohne GoSub

Woran könnte das liegen?
Immerhin ist er die Tabelle so wie es aussah nur noch 3 mal abgegangen bzw. gerade nur einmal.

MfG
Jason

Der_Donnervogel
2009-09-23, 16:25:03
Wo deine Endlosschleife herkommt, ist mir allerdings so oder so schleierhaft. Das dürfte eigentlich nicht passieren.
Ich kenne mich in Excel VBA nicht besonders aus, aber ich vermute mal das liegt darin, dass aktivieren() nicht das tut was es dem Namen nach tun sollte:

Public Function aktivieren()
Tabelle1.Application.EnableEvents = False
End Function

Der_Donnervogel
2009-09-23, 16:29:23
Laufzeitfehler 3
Return ohne GoSub

Woran könnte das liegen?
Vermutlich ist irgendwo im Code das Schlüsselwort "return" drinn (Monger hat das ja in seinem Codefragment verwendet). Das wurde früher benutzt um Prozeduren zu verlassen die mit GoSub aufgerufen wurden. In späteren Versionen von Basic hat man das dann aber mit Exit Sub oder Exit Function gemacht, da GoSub/Return veraltet war und man die nicht mehr verwenden sollte.

wry
2009-09-23, 16:34:56
Habe ebenfalls keinen Schimmer von VB. Nachdem ich aber glaube, dass in der Schleife der Fehler nicht liegen kann, vermute ich dass es etwas mit der Funktion:

Sub Worksheet_Change(ByVal Target As Range)

zu tun hat. Kann es sein, dass diese Funktion jedesmal aufgerufen wird, wenn eine Zelle in deinem Arbeitsblatt geändert wird oder neu geschrieben wird? Falls ja, würde die Funktion sich dauerend selbst aufrufen, was eine Endlosschleife erklären würde.

Der_Donnervogel
2009-09-23, 16:46:54
Sub Worksheet_Change(ByVal Target As Range)

zu tun hat. Kann es sein, dass diese Funktion jedesmal aufgerufen wird, wenn eine Zelle in deinem Arbeitsblatt geändert wird oder neu geschrieben wird? Falls ja, würde die Funktion sich dauerend selbst aufrufen, was eine Endlosschleife erklären würde.Die Funktion würde jedes mal aufgerufen. Wenn aber

Tabelle1.Application.EnableEvents = False

das tut was ich annehme, dann schaltet das die Events ab. Folglich werden in der gesamten Tabelle keine weiteren Events mehr feuern bis das wieder eingeschaltet wird. Allerdings ist die Funktion die das wieder einschalten soll wie von mir geschrieben falsch. Anstatt den Wert wieder auf true zu setzen wird er nochmal auf false gesetzt. Somit bleiben die Events abgeschalten und es tut sich gar nichts mehr, was wohl ähnliche Symptome zeigen wird wie eine Endlosschleife, nehm ich mal an.

Monger
2009-09-23, 16:54:49
Ich kenne mich in Excel VBA nicht besonders aus, aber ich vermute mal das liegt darin, dass aktivieren() nicht das tut was es dem Namen nach tun sollte:

Public Function aktivieren()
Tabelle1.Application.EnableEvents = False
End Function
Hm... jetzt wo du es sagst... "aktivieren" ist eine function, keine Sub - sollte also eigentlich einen Rückgabewert liefern.

...In späteren Versionen von Basic hat man das dann aber mit Exit Sub oder Exit Function gemacht, da GoSub/Return veraltet war und man die nicht mehr verwenden sollte.
Iirc ist genau anders rum: GoSub/Exit Sub ist klassische VB Syntax. "Return" ist hinzu gekommen, weil es jede moderne Sprache kennt, unter anderem auch C#. Vorallem frisst "Return" ja auch im Falle von Funktionen ein Argument als Rückgabewert - das tat Exit Sub wohl nicht.

Aber das nur mal am Rande...

Der_Donnervogel
2009-09-23, 17:09:43
Iirc ist genau anders rum: GoSub/Exit Sub ist klassische VB Syntax. "Return" ist hinzu gekommen, weil es jede moderne Sprache kennt, unter anderem auch C#. Vorallem frisst "Return" ja auch im Falle von Funktionen ein Argument als Rückgabewert - das tat Exit Sub wohl nicht.

Aber das nur mal am Rande...Auch wenn es off-Topic ist. GoSub (bzw. GoTo) und Return waren ganz früher die Kommandos. Später dann (z.B. bei VB 6) waren die sozusagen "deprecated". Sie waren auch nur noch eingeschränkt benutzbar da man sie nur noch innerhalb einer Funktion benutzen konnte aber nicht mehr wie bei "klassischem" Basic kreuz und quer herum und beliebig aus Funktionen heraus und hinein springen konnte. Der Ersatz war das Exit Kommando mit dem man Funktionen und Subs verlassen konnte. Für den Aufruf brauchte man auch kein GoSub mehr sondern schrieb direkt den Funktionsnamen, bzw. man konnte wenn man wollte AFAIR das Schlüsselwort Call verwenden. Die Paarungen waren also GoSub/Return bzw. Call/Exit. Dass das bei VB.Net wieder geändert wurde, hatte ich vergessen. Ich habe es noch nie wirklich eingesetzt sondern nur mal einen kurzen Blick drauf geworfen. Also stimmt in dem Fall, jetzt ist wohl wieder return angesagt.

Edit: Noch eine Ergänzung. Bei VB 6 hat Exit wirklich keinen Rückgabewert gehabt. Das mit dem Rückgabewert wurde so gelöst dass man diesen dem Namen der Funktion zuweisen musste. So in der Art:

Function Hallo() As Integer
Hallo = 10
End Function

wry
2009-09-23, 17:15:18
Die Funktion würde jedes mal aufgerufen. Wenn aber

Tabelle1.Application.EnableEvents = False

das tut was ich annehme, dann schaltet das die Events ab. Folglich werden in der gesamten Tabelle keine weiteren Events mehr feuern bis das wieder eingeschaltet wird. Allerdings ist die Funktion die das wieder einschalten soll wie von mir geschrieben falsch. Anstatt den Wert wieder auf true zu setzen wird er nochmal auf false gesetzt. Somit bleiben die Events abgeschalten und es tut sich gar nichts mehr, was wohl ähnliche Symptome zeigen wird wie eine Endlosschleife, nehm ich mal an.

Ok, das macht Sinn.
Der "Tabelle1.aktivieren"-Aufruf sollte dann aber außerhalb der Schleife (?) und = TRUE sein, wie du schon erwähnt hast.

Hardcoregamer
2009-09-23, 17:28:54
Probiers mal mit .select anstatt .activate

Was möchtest Du mit aktivieren bezwecken?

JasonX
2009-09-24, 07:28:39
Lol,

ich glaub der Rechner will mich wohl auf den Arm nehmen.

Hab unter das

If ActiveCell.Text = "" Then Return


das Exit Sub eingefügt, damit kommt der Laufzeitfehler nicht mehr.

ABER, die FOR-Schleife geht nicht mehr, jetzt sagt der mir
Kompilierungsfehler: NEXT ohne FOR

Nur wenn man in den Code schaut, steht FOR doch DA! Wo wird denn FOR nun beendet das NEXT das nicht erkennt?

MfG

Jason



Private Sub Worksheet_Change(ByVal Target As Range)

Tabelle1.Application.EnableEvents = False
Dim i As Byte

For i = 2 To 10 Step 1


Tabelle1.Range("B" & i).Activate

If ActiveCell.Text = "" Then

Exit Sub

Dim Value As Integer
Select Case ActiveCell.Text

Case Is > 10.3: Value = 0
Case Is > 10: Value = 1
Case Is > 9.7: Value = 2
Case Is > 9.1: Value = 3
Case Is > 8, 8: Value = 4
Case Is > 8.6: Value = 5
Case Else: Value = 6
End Select

Tabelle1.Range("C" & i).Value = Value

Tabelle1.aktivieren
Next i

End Sub
Public Function aktivieren()
Tabelle1.Application.EnableEvents = True
End Function

_Gast
2009-09-24, 07:50:05
Überprüfe nochmal deine Schleifen! Der Fehler kann auch vorkommen, wenn eine andere Schleife nicht geschlossen ist.

Es ist in Visual Basic (und auch VBA) ein Unterschied, ob man die Bedingung einer IF-Abfrage in die selbe Zeile schreibt oder nicht.if x=1 then x=0ist eine korrekte Schreibweise.if x=1 then
x=0dagegen ist nicht richtig! Verteilt man IF und die Bedingung auf mehrere Zeilen, muss zwangsläufig ein ENDIF folgen.if x=1 then
x=0
end ifAnsonsten hast du eine offene Schleife, die zu Fehlermeldungen führt.Eine Anweisung für einen If-Block muß die erste Anweisung in einer Zeile sein. Vor den Schlüsselwörtern Else, ElseIf und End If der Anweisung ist nur eine Zeilennummer oder Zeilenmarke zulässig. Der If-Block muß mit einer End If-Anweisung beendet werden.Quelle: Excel-Hilfe zu VBA

JasonX
2009-09-24, 08:18:51
Es sind alle IF-Abfragen geschlossen mit END IF

Glaube ich kann das ausschließen, da am Anfang sogar ein END IF zuviel drin war, und wir dannach auch keine IF Abfrage mehr hinzugefügt haben.

Kann der fehler nicht an der FOR Schleife liegen?

_Gast
2009-09-24, 08:34:23
Es sind alle IF-Abfragen geschlossen mit END IFIch habe das nur vermutet, weil dein Codeausschnitt zeigtFor i = 2 To 10 Step 1


Tabelle1.Range("B" & i).Activate

If ActiveCell.Text = "" Then

Exit Sub

Dim Value As Integer
Select Case ActiveCell.Text
und da fehlt eindeutig ein ENDIF.

Poste mal den Code genau so, wie du ihn im VBA hast.

JasonX
2009-09-24, 09:25:01
Private Sub Worksheet_Change(ByVal Target As Range)

Tabelle1.Application.EnableEvents = False
Dim i As Byte

For i = 2 To 10 Step 1


Tabelle1.Range("B" & i).Activate

If ActiveCell.Text = "" Then
Exit Sub
End If

Dim Value As Integer
Select Case ActiveCell.Text

Case Is > 10.3: Value = 0
Case Is > 10: Value = 1
Case Is > 9.7: Value = 2
Case Is > 9.1: Value = 3
Case Is > 8, 8: Value = 4
Case Is > 8.6: Value = 5
Case Else: Value = 6
End Select

Tabelle1.Range("C" & i).Value = Value

Tabelle1.aktivieren

Next i

End Sub
Public Function aktivieren()
Tabelle1.Application.EnableEvents = True
End Function



So folgendes:

In B2 trage ich einen Wert ein und er gibt in C2 den passenden Wert aus.
In B3 trage ich einen Wert ein und er beginnt 3-4 mal B2 und B3 zu durchlaufen, dann trägt er den Wert in C3 ein.
In B4 trage ich einen Wert ein und der beginnt endlos B2-B4 abzurufen, trägt aber den Wert in C4 ein.

Also ist da noch ein kleiner Wurm drinnen.

MfG
Jason

Monger
2009-09-24, 09:54:59
Blöde Idee, aber wäre es denkbar dass der "Range" nicht so definiert ist wie du dir das vorstellst?! Heißt Range("C2") eventuell, der Bereich von A1 bis C2?

Möglicherweise musst du eine andere Überladung von Range nutzen - eine die auch die Breite und Länge des Bereichs angibt. Du willst schließlich nur eine einzige Zelle auswählen.

Möglicherweise hast du es hier dann eben nicht mit einer Endlosschleife zu tun, sondern nur mit einer Operation die algorithmisch dermaßen zeitintensiv ist, dass sie nie fertig wird. Das wäre natürlich der Fall, wenn du immer und immer wieder den selben Bereich im "Range" überbügeln würdest.

robobimbo
2009-09-24, 09:59:59
Range("C2") ist schon richtig, aber warum .activate und nicht .select?

activate brauchst du nur wenn du wirklich einen bereich markiert hast und aus diesem bereich eine einzelne zelle aktivieren willst. für deine anwendung tut es Range("C2").Select auch

_Gast
2009-09-24, 10:10:54
Also der Fehler ist ganz einfach. ;)

Du verwendest das Ereignis "Change" des Worksheet Objekts. Dieses wird jedes mal aufgerufen, wenn sich auf dem Arbeitsblatt etwas ändert.Tritt auf, wenn Zellen des Arbeitsblatts durch den Benutzer oder durch eine externe Verknüpfung geändert werden.Quelle: Hilfe Excel VBA

Das bedeutet, dass dieses Ereignis nicht nur dann aufgerufen wird, wenn du etwas im Arbeitsblatt änderst, sondern natürlich auch, wenn dein Code etwas ändert. Die Folge ist, dass deine Schleife eine Zelle ändert und damit das Ereignis erneut aufruft und wieder die Zelle ändert und wieder das Ereignis aufruft und...

Das ist dir Ursache für die Endlosschleife.

Das kannst du verhindern, indem du im Ereignis prüfst, ob es bereits ausgeführt wird. Am einfachsten geht das über eine logische Variable. Hier der lauffähige Code:Private Sub Worksheet_Change(ByVal Target As Range)

Static x As Boolean

If x = True Then
Exit Sub
End If

x = True

Tabelle1.Application.EnableEvents = False
Dim i As Byte

For i = 2 To 10 Step 1

Tabelle1.Range("B" & i).Activate

If ActiveCell.Text = "" Then
x = False
Exit Sub
End If

Dim Value As Integer
Select Case ActiveCell.Text
Case Is > 10.3: Value = 0
Case Is > 10: Value = 1
Case Is > 9.7: Value = 2
Case Is > 9.1: Value = 3
Case Is > 8, 8: Value = 4
Case Is > 8.6: Value = 5
Case Else: Value = 6
End Select

Tabelle1.Range("C" & i).Value = Value
Tabelle1.aktivieren
Next i

x = False

End Sub

Public Function aktivieren()

Tabelle1.Application.EnableEvents = True

End Function

wry
2009-09-24, 10:27:44
@_Gast
Soweit ich das jetzt verstanden hab, löst sich die Worksheet_Change Funktion durch das ändern von Zellen selbst aus. Das soll nun aber verhindert werden indem die Events abgeschaltet werden.

Warum werden die Events aber in der Schleife jedesmal wieder eingeschaltet? Sollten die nicht erst wieder aktiviert werden, wenn diese Sub nichts mehr ändert?

Sprich "Tabelle1.aktivieren" ans Ende der Sub, somit sollte das Workaround mit der logischen Variable dann überflüssig sein?



Private Sub Worksheet_Change(ByVal Target As Range)

Tabelle1.Application.EnableEvents = False
Dim i As Byte

For i = 2 To 10 Step 1

Tabelle1.Range("B" & i).Activate

If ActiveCell.Text = "" Then
Exit Sub
End If

Dim Value As Integer
Select Case ActiveCell.Text

Case Is > 10.3: Value = 0
Case Is > 10: Value = 1
Case Is > 9.7: Value = 2
Case Is > 9.1: Value = 3
Case Is > 8, 8: Value = 4
Case Is > 8.6: Value = 5
Case Else: Value = 6
End Select

Tabelle1.Range("C" & i).Value = Value

Next i

Tabelle1.aktivieren

End Sub


Public Function aktivieren()
Tabelle1.Application.EnableEvents = True
End Function

JasonX
2009-09-24, 10:50:21
Also der Fehler ist ganz einfach. ;)

Du verwendest das Ereignis "Change" des Worksheet Objekts. Dieses wird jedes mal aufgerufen, wenn sich auf dem Arbeitsblatt etwas ändert.Quelle: Hilfe Excel VBA

Das bedeutet, dass dieses Ereignis nicht nur dann aufgerufen wird, wenn du etwas im Arbeitsblatt änderst, sondern natürlich auch, wenn dein Code etwas ändert. Die Folge ist, dass deine Schleife eine Zelle ändert und damit das Ereignis erneut aufruft und wieder die Zelle ändert und wieder das Ereignis aufruft und...

Das ist dir Ursache für die Endlosschleife.

Das kannst du verhindern, indem du im Ereignis prüfst, ob es bereits ausgeführt wird. Am einfachsten geht das über eine logische Variable. Hier der lauffähige Code:Private Sub Worksheet_Change(ByVal Target As Range)

Static x As Boolean

If x = True Then
Exit Sub
End If

x = True

Tabelle1.Application.EnableEvents = False
Dim i As Byte

For i = 2 To 10 Step 1

Tabelle1.Range("B" & i).Activate

If ActiveCell.Text = "" Then
x = False
Exit Sub
End If

Dim Value As Integer
Select Case ActiveCell.Text
Case Is > 10.3: Value = 0
Case Is > 10: Value = 1
Case Is > 9.7: Value = 2
Case Is > 9.1: Value = 3
Case Is > 8, 8: Value = 4
Case Is > 8.6: Value = 5
Case Else: Value = 6
End Select

Tabelle1.Range("C" & i).Value = Value
Tabelle1.aktivieren
Next i

x = False

End Sub

Public Function aktivieren()

Tabelle1.Application.EnableEvents = True

End Function


Ok, damit funktioniert es, er geht jetzt jede Zelle einzeln ab.

Super, danke.

Bleibt nur noch eine sache, der macht das nur einmal bis 10
dannach wenn ich wieder in b2 von vorne anfangen will macht er das nicht mehr. Dann ändern sich keine Werte mehr und er springt immer zur letzten Zeile, wenn ich z.B. B4 und B6 ändern will muss ich nach jedem Eintrag immerwieder hochgehen.

Mfg

Jason

wry
2009-09-24, 11:08:27
Ok, damit funktioniert es, er geht jetzt jede Zelle einzeln ab.

Super, danke.

Bleibt nur noch eine sache, der macht das nur einmal bis 10
dannach wenn ich wieder in b2 von vorne anfangen will macht er das nicht mehr. Dann ändern sich keine Werte mehr und er springt immer zur letzten Zeile, wenn ich z.B. B4 und B6 ändern will muss ich nach jedem Eintrag immerwieder hochgehen.

Mfg

Jason


Ich glaub das liegt an dem Workaround
Static x As Boolean

If x = True Then
Exit Sub
End If

x = True

Wenn die Sub einmal ausgeführt wird, dann wird sie beim nächsten mal nicht mehr ausgeführt weil x = True.

Funktioniert meine Variante oben nicht? Ich hab leider kein Excel auf dem Rechner und kanns nicht testen ;(

Edit:
Hab übersehn, dass _Gast das x zuletzt wieder auf False setzt, sorry :(


Edit2:
In dem Fall werden die Events nicht mehr eingeschaltet, vielleicht macht das Probleme?
If ActiveCell.Text = "" Then
x = False
Exit Sub
End If

Korrektur:
If ActiveCell.Text = "" Then
x = False
Tabelle1.aktivieren
Exit Sub
End If


Ich würds mal so ausprobieren :)
Private Sub Worksheet_Change(ByVal Target As Range)

Tabelle1.Application.EnableEvents = False
Dim i As Byte

For i = 2 To 10 Step 1

Tabelle1.Range("B" & i).Activate

If ActiveCell.Text = "" Then
Tabelle1.aktivieren
Exit Sub
End If

Dim Value As Integer
Select Case ActiveCell.Text

Case Is > 10.3: Value = 0
Case Is > 10: Value = 1
Case Is > 9.7: Value = 2
Case Is > 9.1: Value = 3
Case Is > 8, 8: Value = 4
Case Is > 8.6: Value = 5
Case Else: Value = 6
End Select

Tabelle1.Range("C" & i).Value = Value

Next i

Tabelle1.aktivieren

End Sub


Public Function aktivieren()
Tabelle1.Application.EnableEvents = True
End Function

JasonX
2009-09-24, 11:25:41
Nein, er führt es dann garnicht aus.

Warum auch immer.

Mom, ich trag mal nach. (War zu langsam:D)

/Edith:

Ja, bleibt nur noch das Problem das er immer an die letzte Stelle mit Werten in der Spalte B rutscht.
Sollte aber wie normal wenn ich B5 bearbeite in B6 rutschen usw.

wry
2009-09-24, 11:49:59
Da weiß ich jetzt leider auch nicht mehr weiter :redface:

Vielleicht hilfts wenn du anstatt "activate" "select" verwendest? Aber das ist jetzt mehr ein Schuss ins Blaue :biggrin:


Private Sub Worksheet_Change(ByVal Target As Range)

Tabelle1.Application.EnableEvents = False
Dim i As Byte

For i = 2 To 10 Step 1

Tabelle1.Range("B" & i).Select

If ActiveCell.Text = "" Then
Tabelle1.aktivieren
Exit Sub
End If

Dim Value As Integer
Select Case ActiveCell.Text
Case Is > 10.3: Value = 0
Case Is > 10: Value = 1
Case Is > 9.7: Value = 2
Case Is > 9.1: Value = 3
Case Is > 8, 8: Value = 4
Case Is > 8.6: Value = 5
Case Else: Value = 6
End Select

Tabelle1.Range("C" & i).Value = Value

Next i

Tabelle1.aktivieren

End Sub


Public Function aktivieren()
Tabelle1.Application.EnableEvents = True
End Function

JasonX
2009-09-24, 11:52:29
Hab ich schon, ist schon auf select.

Sorry das ich nicht den akutellen Code rangehängt habe.



Private Sub Worksheet_Change(ByVal Target As Range)

Static x As Boolean

If x = True Then
Exit Sub
End If

x = True


Tabelle1.Application.EnableEvents = False
Dim i As Byte

For i = 2 To 50 Step 1


Tabelle1.Range("B" & i).Select

If ActiveCell.Text = "" Then
Tabelle1.aktivieren


x = False

Exit Sub
End If

Dim Value As Integer
Select Case ActiveCell.Text

Case Is > 10.3: Value = 0
Case Is > 10: Value = 1
Case Is > 9.7: Value = 2
Case Is > 9.1: Value = 3
Case Is > 8.8: Value = 4
Case Is > 8.6: Value = 5
Case Else: Value = 6
End Select

Tabelle1.Range("C" & i).Value = Value


Tabelle1.aktivieren
Next i

x = False
End Sub
Public Function aktivieren()
Tabelle1.Application.EnableEvents = True
End Function

wry
2009-09-24, 11:58:22
Wenn ich dich richtig verstanden hab, ist nach dem Ausführen des Skript die letzte Zelle in der B-Spalte markiert (also immer B20) ?

Falls es das ist, könntest du es verhindern, indem du einfach die "aktuell selektierte Zelle"+1 selektierst (am Ende der Sub)


Ich weiß nicht ob das geht:
Private Sub Worksheet_Change(ByVal Target As Range)

Static x As Boolean

If x = True Then
Exit Sub
End If

x = True


Tabelle1.Application.EnableEvents = False
Dim i As Byte

For i = 2 To 50 Step 1


Tabelle1.Range("B" & i).Select

If ActiveCell.Text = "" Then
Tabelle1.aktivieren


x = False

Exit Sub
End If

Dim Value As Integer
Select Case ActiveCell.Text

Case Is > 10.3: Value = 0
Case Is > 10: Value = 1
Case Is > 9.7: Value = 2
Case Is > 9.1: Value = 3
Case Is > 8.8: Value = 4
Case Is > 8.6: Value = 5
Case Else: Value = 6
End Select

Tabelle1.Range("C" & i).Value = Value


Tabelle1.aktivieren
Next i

Tabelle1.Range(Target.Address).Select

x = False

End Sub
Public Function aktivieren()
Tabelle1.Application.EnableEvents = True
End Function

robobimbo
2009-09-24, 12:41:27
Versuch mal das


Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
Debug.Print "Entering Worksheet Change Event"
EvaluateColumn
ActiveSheet.Range(Target.Cells).Select
Application.EnableEvents = True
End Sub

Public Sub EvaluateColumn()
Dim i As Byte
Dim Value As Integer

For i = 2 To 10
ActiveSheet.Range("B" & i).Select
If ActiveCell.Text <> "" Then
Select Case ActiveCell.Text
Case Is > 10.3: Value = 0
Case Is > 10: Value = 1
Case Is > 9.7: Value = 2
Case Is > 9.1: Value = 3
Case Is > 8, 8: Value = 4
Case Is > 8.6: Value = 5
Case Else: Value = 6
End Select
ActiveSheet.Range("C" & i).Value = Value
End If
Next i
End Sub


Normalerweise reicht das Abschalten der Events damit es zu keiner Rekursion kommt.
Zusätzlich markiert er noch die alte Zelle / Zellenbereich falls du an anderer Stelle in dieser Tabelle was geändert hast

JasonX
2009-09-24, 14:01:12
Hmm.

Nein, hat leider nicht funktionert.

Springt immernoch in die letzte Zelle in der ein Wert geschrieben ist.

:frown:

Mist,

hab gehofft das ich das heute noch zum laufen bekomme...

... naja, bin dann vielleicht morgen ansonsten erst wieder in einer Woche on um da weiter machen zu können.

Danke aber trozdem für die zahlreiche Hilfe, bin immerhin schon ein riesen Stück weiter dank euch. :hug:

MfG
Jason

_Gast
2009-09-24, 14:46:17
Bleibt nur noch eine sache, der macht das nur einmal bis 10 dannach wenn ich wieder in b2 von vorne anfangen will macht er das nicht mehr. Dann ändern sich keine Werte mehr und er springt immer zur letzten Zeile, wenn ich z.B. B4 und B6 ändern will muss ich nach jedem Eintrag immerwieder hochgehen.

Mfg

JasonAuch das ist logisch. Der macht genau das, was du ihm als Programmierer sagst! ;)

In der Schleife gehst du so lange durch die Werte, bis keiner mehr kommtIf ActiveCell.Text = "" Then
x = False
Exit Sub
End Ifoder die Schleife zu Ende ist. So lange also keine Werte in den Zellen stehen, bricht er immer an der ersten leeren Zeile ab. Sind aber alle Werte eingetragen, dann läuft deine Schleife natürlich immer bis nach unten, weil ja ActiveCell.Text nie mehr leer ist.

Auch das kannst du einfach umgehen, indem du dir zu Beginn der Schleife den aktuellen Status merkst und am Ende wieder herstellst.Private Sub Worksheet_Change(ByVal Target As Range)

Static x As Boolean

If x = True Then
Exit Sub
End If

x = True

Tabelle1.Application.EnableEvents = False
Dim i As Byte

y = ActiveCell.Address

For i = 2 To 10 Step 1

Tabelle1.Range("B" & i).Activate

If ActiveCell.Text = "" Then
Tabelle1.Range(y).Activate
x = False
Exit Sub
End If

Dim Value As Integer
Select Case ActiveCell.Text
Case Is > 10.3: Value = 0
Case Is > 10: Value = 1
Case Is > 9.7: Value = 2
Case Is > 9.1: Value = 3
Case Is > 8, 8: Value = 4
Case Is > 8.6: Value = 5
Case Else: Value = 6
End Select

Tabelle1.Range("C" & i).Value = Value
Tabelle1.aktivieren
Next i

Tabelle1.Range(y).Activate

x = False

End Sub
Public Function aktivieren()

Tabelle1.Application.EnableEvents = True

End Function

robobimbo
2009-09-24, 19:56:46
Wenn ihr das "Tabelle1.aktivieren" aus der Schleife rausnimmt (Das aktiviert ja die Change Events wieder) dann braucht ihr das Status Konstrukt mit true / false nicht