Excel VBA Schleife, Case Else und Errorhandling Verschachtelung

tobias_2

Cadet 4th Year
Registriert
Nov. 2009
Beiträge
84
Hallo,

Ich habe eine For Schleife gebaut, die bestimmte Spalten durch iteriert und per Select Case vergleicht, ob bestimmte Strings in den Zellen stehen.

Nun möchte ich beim Eintritt des Case Else ein Errorhandling durchführen.
Allerdings springt er bei folgendem Code direkt bei Eintritt des Case Else in den Errorhandler und läuft die Schleife und den Restcode nicht zuende:

Code:
Case Else
fehler = Cells(i, 11)
fehler_g = fehler_g & vbNewLine & fehler
GoTo Errorhandler

Ich möchte diesen fehler_g dann im Errorhandler als Meldung ausgeben. Ich kann natürlich auch einfach eine MsgBox in diesen Case Else einbauen, aber dann gibt er mir ja mehrere MsgBoxen aus, jeweils mit einem Wert mehr aus (falls es mehrere Fälle gibt, die sich von den von mir definierten unterscheiden)

Alternativ kann ich komplett unterhalb der Schleife eine MsgBox ausgeben lassen, die dann alles perfekt darstellt.
Aber diese MsgBox erscheint dann ja auch, falls es keinen Case Else gibt.
Dann müsste man irgendwas derart konzipieren:
Code:
If Case else = true then
msgbox "blabla"
End If

Hoffe ihr versteht mein Problem, mein Kopf qualmt schon vom 6 stündigen programmieren :D
 
Hallo,

ich vermute, es ist wieder nicht möglich, aufgrund firmeninterna mehr Code als die paar Zeilen zu posten? :freak: :)

Allerdings springt er bei folgendem Code direkt bei Eintritt des Case Else in den Errorhandler und läuft die Schleife und den Restcode nicht zuende
soll heissen, die Codezeilen fehler und fehler_g werden nicht abgearbeitet?..evtl. testen mit F8 Einzelschrittmodus

ohne wirklich genau zu verstehen (so wie manch anderer bei dem ein oder anderen post von dir ;) )
würd ich vorschlagen im case else-teil (dieser dient optional ja bekanntlich dazu, evtl. Fehler während der Laufzeit abzufangen)
eine Variable zu fühlen.

ob das funzt weiss ich nicht auswendig:
If Case else = true

und mit if-then diese variable NACH der selectcase oder vielleicht auch NACH der For-Schleife auf Inhalt abfragen und entsprechend
dann eine msgbox mit der variable auszugeben.


hmm..weiss nicht, ob das:
Case Else
fehler = Cells(i, 11)
fehler_g = fehler_g & vbNewLine & fehler
GoTo Errorhandler

so "sauber" programmiert ist bzw. ein goto in einem case else oder auch in einem case üblich ist

p.s. danke für die blumen wegen "mappe1.activate" :)
 
soll heissen, die Codezeilen fehler und fehler_g werden nicht abgearbeitet?..evtl. testen mit F8 Einzelschrittmodus
Logisch, dass es nicht abgearbeitet wird, da "GoTo Errorhandler" direkt den anderen Code überspringt.

und mit if-then diese variable NACH der selectcase oder vielleicht auch NACH der For-Schleife auf Inhalt abfragen und entsprechend
dann eine msgbox mit der variable auszugeben.
DAS versuche ich zu erreichen. ABER "If Case else = true" funktioniert nicht, sonst hätte ich ja schon längt die Lösung :S

----------------------------------------------------------------------------------------------------------------------------------------
Also in dem Programm werden mit einer for-Schleife 2 Spalten durch iteriert. Also z.B. Spalte A und B.
Nur wenn beide Spalten einen Wert enthalten wird (sagen wir) Spalte A per Select Case mit bestimmten Strings (die ich in den einzelnen Cases definiert habe) verglichen.

Wenn ein String auftaucht, den ich nicht definiert habe, geht´s ab in den => Case Else

Hier wird dann der Wert aus Spalte A und Spalte B jeweils in eine Variable gepackt (fehler) und per Zwischenspeicher (fehler_g) um weitere "fehlerhafte" Zeilen erweitert.

Hab mir nun folgendes überlegt:
Falls Case Else "existieren" dann soll (nachdem der restliche Code dieses Buttons abgearbeitet ist) eine andere UserForm geöffnet werden und die jeweiligen Einzelwerte jedes Schleifendurchlaufs (Variable: fehler) in einer Textbox der neuen Userform übertragen werden.

Die 2. Userform sieht ungefähr wie folgt aus:
UserForm2.png

In der ComboBox wird es dann verschiedene Einträge geben, die je nach Auswahl die Werte aus der Textbox zu bestimmten Zellen einer neuen Datei hinzufügen. (das krieg ich selber hin)

Beim klicken des Buttons ">>" soll (falls vorhanden) der nächste Case Else Wert in der TextBox erscheinen.

Wäre auch möglich sowas direkt in den Case Else einzubauen, wenn es eine Funktion oder Methode gäbe, die den letzten Schleifendurchlauf oder Eintritt in den Select Case angibt.
 
Hi,

Logisch, dass es nicht abgearbeitet wird, da "GoTo Errorhandler" direkt den anderen Code überspringt.
jaaa..sicher wird zu Errorhandler gesprungen, aber ich kann mir nicht vorstellen, dass
Code:
fehler = Cells(i, 11)
fehler_g = fehler_g & vbNewLine & fehler
nicht abgearbeitet werden. wobei ich mir unsicher bin ob
Code:
fehler = Cells(i, 11)
so korrekt ist. du willst doch den Inhalt der Zelle (i,11) an fehler übergeben oder? aber egal..bin mehr mit word-vba vertraut.


Ich hab hier mal ein Beispiel gemacht..zwar in word aber vergleichbar:

Code:
Private Sub testeingabe_Exit(ByVal Cancel As MSForms.ReturnBoolean)

Select Case testeingabe.Value
    Case Is = "1"
    MsgBox "1 stimmt"
    Case Is = "2"
    MsgBox "2 stimmt"
    Case Is = "3"
    MsgBox "3 stimmt"
    Case Else
    'bolelse = True
    strfalscheEingabe = strfalscheEingabe & testeingabe.Value & " als " & Str(intEingabeanzahl) & " .Eingabe war falsch" & vbNewLine
    
End Select

answer = MsgBox("Nochmal?", vbYesNo)
If answer = vbYes Then
    testeingabe.SetFocus
End If
If answer = vbNo Then
    Test4.txtAusgabefehler.Value = strfalscheEingabe
    Test4.Show
End If

intEingabeanzahl = intEingabeanzahl + 1

End Sub

im übrigen könntest du eine booleanvariable im else-teil auf true setzen und diese dann ausserhalb der schleife abfragen und die msgbox ausgeben.

Vielleicht hilft dir das weiter und kannst es bei dir umsetzen.

hier:
Code:
If answer = vbNo Then
    Test4.txtAusgabefehler.Value = strfalscheEingabe
    Test4.Show
End If

werden die Fehler ins einer anderen Userform (Test4) in einer Textbox ausgegeben.
 
Code:
1.fehler = Cells(i, 11)
2.fehler_g = fehler_g & vbNewLine & fehler
Es wird abgearbeitet, allerdings nur beim ersten Case Else Fall, da er dann ja in diesen reingeht, zuerst diesen Code einmal abarbeitet, dann zum GoTo geht und direkt zum Errorhandler springt.
Aber das nur als Info.

Code:
fehler = Cells(i, 11)
Also so übergebe ich die ganzen Zelleninhalte auch an andere Variablen und das klappt prima.

So jetzt zum eigentlichen:
im übrigen könntest du eine booleanvariable im else-teil auf true setzen und diese dann ausserhalb der schleife abfragen und die msgbox ausgeben.
DANKE! Das hat mir schonmal sehr weitergeholfen und war eine gute Idee.
Dadurch kann ich jetzt außerhalb der Schleife einfach mit If abfragen, ob die boolsche Variable True ist und je nachdem eine MsgBox ausgeben.

werden die Fehler ins einer anderen Userform (Test4) in einer Textbox ausgegeben.
So, jetzt die größere Schwierigkeit.

hier nochmal die 2. Userform zur Veranschaulichung:
UserForm2.png

Ich möchte die 2. Userform so oft öffnen, wie es Case Else Fälle gibt.
Wenn es zum Beispiel 3 Fälle gibt, soll die Userform 3 Mal geöffnet werden und jeweils die einzelnen Werte (aus der Variable Fehler)
in der Textbox (oben) ausgegeben werden.

Nun könnte ich einfach in den Case Else Fall folgendes hinzufügen:
Code:
Case Else
fcase = True
Z = Z + 1

fehler = UCase(bezeichnung) & vbTab & CDbl(Cells(i, 11))
fehler_g = fehler_g & vbNewLine & fehler

UserForm2.Show
UserForm2.TextBox1 = fehler
End Select

Dann würde er mir bei 3 Case Else Fällen tatsächlich diese Userform 3 Mal öffnen und die jeweiligen Werte anzeigen.

Was mich allerdings wundert, ist dass die Werte falsch angezeigt werden:
Es wird der Wert des 1. Case Else Falls zweimal hintereinander angezeigt und beim 3. öffnen der Userform noch der 2. Case Else Fall und das war´s.

Aber was jetzt die eigentliche Schwierigkeit darstellt:
Ich möchte, dass erst der gesamte Restcode abgearbeitet wird und dann erst die 2. Userform (abhängig von den auftretenden Fällen entsprechend oft) geöffnet wird.
Sprich die Anweisung:
UserForm2.Show
UserForm2.TextBox1 = fehler

nicht direkt im Case Else stehen.

Wie realisiere ich das?
Ich dachte schon an soetwas wie eine Auslagerung in eine extra Funktion und dann die Call Methode in den Case Else, aber dann würde er die Userformen ja td direkt beim Auftreten des Case Else öffnen und nicht erst am Ende, sprich nach der MsgBox.

Hoffe man wird daraus schlau..
 
hi,

DANKE! Das hat mir schonmal sehr weitergeholfen und war eine gute Idee.
prima..es geht weiter :)

Was mich allerdings wundert, ist dass die Werte falsch angezeigt werden:
Es wird der Wert des 1. Case Else Falls zweimal hintereinander angezeigt und beim 3. öffnen der Userform noch der 2. Case Else Fall und das war´s.
sorry..kann ich grad nicht nachvollziehen.

Ich möchte die 2. Userform so oft öffnen, wie es Case Else Fälle gibt.
Wenn es zum Beispiel 3 Fälle gibt, soll die Userform 3 Mal geöffnet werden und jeweils die einzelnen Werte (aus der Variable Fehler)
in der Textbox (oben) ausgegeben werden.
Ich vermute dies:
Code:
Z = Z + 1
zählt die Anzahl der Case Else Durchläufe?
Dann würde ich dieses Z als Variable für eine For-Schleife verwenden. In dieser For-Schleife würde ich die besagte Userform mit Einzelausgabe der Fehler machen.
fehler_g würde ich in der For-Schleife ausplitten an vbNewLine, sodass du (wieder) die einzelnen Fehlerwerte hast.

Aber was jetzt die eigentliche Schwierigkeit darstellt:
Ich möchte, dass erst der gesamte Restcode abgearbeitet wird und dann erst die 2. Userform (abhängig von den auftretenden Fällen entsprechend oft) geöffnet wird.
Sprich die Anweisung:
UserForm2.Show
UserForm2.TextBox1 = fehler

nicht direkt im Case Else stehen.
Also praktisch ausserhalb der Select-Anweisung bzw. ausserhalb von
Also in dem Programm werden mit einer for-Schleife 2 Spalten durch iteriert.
?

Dann mach das doch so :)..oder ich versteh noch etwas falsch :rolleyes:

sprich: unterhalb der For-Schleife, die die Spalten durchiteriert eine For-Schleife mit Z
in der jeweils pro fehler-Wert (aufgesplittetes fehler_g an vbnewline) die userform erscheint.

Alternative:
die Variable fehler als Array. aber auch hier die For-Schleife mit Z und in dieser die For-Schleife, die die Array-Werte durchläuft. :)
 
Alternative:
die Variable fehler als Array. aber auch hier die For-Schleife mit Z und in dieser die For-Schleife, die die Array-Werte durchläuft.
Ich will das jetzt echt so machen.

Aber ich kriege es noch nicht so richtig hin..
Code:
Dim fwert(3) As Integer       'wie mache ich das ohne eine Länge festzulegen? 
                                                   'Kenne nur ArrayList aus Java

'For Schleife...

wert = Cells(i, 11)

'Select Case ...

Case Else

fcase = True
fwert(z) = wert       'schmeißt doch die einzelnen Werte in den Array? 
                             'Nacheinander? Also den ersten auf Platz fwert(0) usw.
Z = Z + 1

End Select

For y = 0 To Z

UserForm2.Show
UserForm2.TextBox1 = fwert(y)

Next y
Helf mir :S
 
Code:
Dim fwert(3) As Integer
'wie mache ich das ohne eine Länge festzulegen?
gib mal in die vba-hilfe 'redim' ein und schau dir das 'ReDim-Anweisung (Beispiel)' an
je nachdem statt integer kann es bei dir auch variant oder string als datentyp sein..je nach Inhalt der Zellwerte die in die variable geschrieben werden.

dein Thema " Excel VBA Schleifeninhalte erst später ausgeben " könnt ja auch mal geschlossen werden. Es sei denn du möchtest gerne an der Spitze der Themenliste bleiben :D ;)
 
je nachdem statt integer kann es bei dir auch variant oder string als datentyp sein..je nach Inhalt der Zellwerte die in die variable geschrieben werden.
Es sind genau 2 Variablen (einmal vom Typ String und vom Typ Double), sprich ich brauche später 2 Array-Variablen.

Code:
Dim fwert(3) As Integer
kann man die Variable eig auch belegen, ohne sie vorher zu "dimen"? Ich mach das eig nie, obwohl ich weiss, dass es eig besser wäre.

Code:
fwert(z) = wert
Mit dieser Zuweisung im Select Case, schmeiße ich doch die Werte korrekt in den Array oder? Also den 1. Wert auf Stelle fwert(0) etc.??
Ist das Z standardmäßig mit einer 0 belegt? (schließt eig fast die Frage drüber mit ein)

Code:
For y = 0 To Z
 
UserForm2.Show
UserForm2.TextBox1 = fwert(y)
 
Next y
Soweit klappt das eig schon, nur ist die erste UserForm die ausgegeben wird leer?!?! Und dann kommen erst die 3 Werte (wenn ich den Array mit fwert(2) anlege, habe ich das gleiche Problem und der letzte Wert wird nichtmehr ausgegeben.

Gibt es keine Schleife mit der man den Array durch iterieren kann und prüft, ob es noch weitere Werte im Array gibt und wenn Ja diesen dann in der TextBox1 der UserForm entsprechend ausgibt? (Kenne sowas von JAVA)

Noch eine Frage: Muss ich für diese 2. Schleife eine extra Variable (wie hier y benutzen)? Finde das iwie etwas unschön..

gib mal in die vba-hilfe 'redim' ein und schau dir das 'ReDim-Anweisung (Beispiel)' an
Das guck ich mir morgen früh mal an :)

dein Thema " Excel VBA Schleifeninhalte erst später ausgeben " könnt ja auch mal geschlossen werden. Es sei denn du möchtest gerne an der Spitze der Themenliste bleiben
Ja sorry, aber ich hab damit jetzt schon soviel Zeit verbracht.. Und muss noch soviel im Programm hinzufügen, deshalb war ich etwas in Eile :D
 
Ich bin verwirrt…

Case Else kann immerhin das erfassen was bei Case das Else verzapft hat.

Eine Gesamtfehlerliste tue ich eigentlich nicht gern in ein Array, korrekter: Feldvariable, müsste ich würde ich großzügig als String DIMen und (meine Macke) in (0) mitzählen wie viele Fehler es gibt. Meist nehme ich schnöde einen String den ich nach dem Meldungstext (den ich in Else aufbereiten würde) um vbCr ergänze um den nächsten Fehler dranzuhängen. Das taugt für MsgBox, für eine Liste als DropDown latürnich weniger.

Eine «Fehlerbehandlungsroutine» würde ich vom Gedanken her anders definieren, als nur, soweit ich das hier kapiert habe, eine einfach Unfälle-Liste beim Durchlaufen zu erstellen. Könnte es sein, dass du für eine kleine Sache zu viel Aufwand anstrengst der einer gut gemeinten, aber nicht effizienten Idee folgt?

CN8
 
Könnte es sein, dass du für eine kleine Sache zu viel Aufwand anstrengst der einer gut gemeinten, aber nicht effizienten Idee folgt?
Eig ist das sogar ein sehr wichtiger Bestandteil des Programms..

Ich muss es schon mit einem Array machen, da ich mit den einzelnen Werten weiterarbeiten möchte (jeweils Ausgabe in Textbox 1 Userform 2)

müsste ich würde ich großzügig als String DIMen und (meine Macke) in (0) mitzählen wie viele Fehler es gibt. Meist nehme ich schnöde einen String den ich nach dem Meldungstext (den ich in Else aufbereiten würde) um vbCr ergänze um den nächsten Fehler dranzuhängen. Das taugt für MsgBox, für eine Liste als DropDown latürnich weniger.
Es sind aber u.a. Integer-Werte, mit denen ich noch weiterrechnen muss.

Sooo, es klappt jetzt scheinbar soweit :)

Code:
Dim fbezeichnung(30)        'Max. Belegung wird wohl nicht größer als 30 sein.
Dim fwert(30)        
z = 0

'For Schleife...
 
bezeichnung = Cells(i, 4) 

'Select Case ...

Case Else                
fcase = True
                
fbezeichnung(z) = bezeichnung
fwert(z) = CDbl(Cells(i, 11))
                
 z = z + 1
               
End Select
'Ende Schleife

If fcase = True Then
For znew = 0 To z - 1        'z - 1, damit am Ende keine leere UserForm ausgegeben wird
        UserForm2.TextBox1 = fbezeichnung(znew) & vbTab & fwert(znew)          
'       musste ich mit der Zeile drunter tauschen => Dadurch hatte ich in der 1. UserForm keine Werte
        UserForm2.Show
Next znew
End If

Code:
Dim fbezeichnung(30)
Welcher Datentyp wird hier festgelegt?!?

Gibt es keine Schleife in VBA, die im Rumpf prüft, ob weitere Elemente im Array sind und je nachdem diese Zurückliefert?
 
moin :),

Welcher Datentyp wird hier festgelegt?!?
string oder?

Ich muss es schon mit einem Array machen, da ich mit den einzelnen Werten weiterarbeiten möchte (jeweils Ausgabe in Textbox 1 Userform 2)
hmm..mir kam da noch der Gedanke statt der Textbox 1 in UF2 ein Listenfeld oder Combobox zu verwenden,
falls die Daten aus dem Array "nur" in die Textbox1 gefüllt werden.

Frage nebenbei: Wieso muss je Fehlerwert die Userform2 immer wieder erscheinen?...bei mehreren Fehlerwerten wäre mir als Nutzer das ein wenig lästig und hat ein wenig den Charakter eines Programmfehlers wenn nach Buttonclick die gleiche UF wieder erscheint (wennauch mit anderen Daten)
 
Zurück
Oben