Supportnet / Forum / Skripte(PHP,ASP,Perl...)
VBA mit Excel - Problem bei Schleife
Frage
Hallo,
ich habe folgendes Problem:
Ich habe eine Funktion geschrieben, die bei Click (Userform) erst prüft, ob der Datensatz in der Tabelle schon verfügbar ist, und dann entweder eine Fehlermeldung in Form einer MsgBox ausgibt, oder den Datensatz in die Tabelle überträgt. Der Quelltext sieht folgendermaßen aus:
***
Private Sub CommandButtonOK_Click()
Dim zeile As Integer
zeile = 4
If TextBoxTitel.Value = Sheets("DVD").Cells(zeile, 1).Value Then 'Überprüfen, ob Titel schon vorhanden ist
MsgBox "Fehler! Eine DVD mit diesem Titel ist bereits vorhanden!"
Else:
Do While zeile < 500 'Zeilenprüfung der Tabelle um Überschreiben zu verhindern
If Sheets("DVD").Cells(zeile, 1).Value = "" Then
Exit Do
Else: zeile = zeile + 1
End If
Loop
Sheets("DVD").Cells(zeile, 1).Value = TextBoxTitel.Value 'Übertragen in Tabelle
Sheets("DVD").Cells(zeile, 2).Value = ComboBoxJahr.Value
Sheets("DVD").Cells(zeile, 3).Value = ComboBoxDisks.Value
Sheets("DVD").Cells(zeile, 4).Value = TextBoxLaenge.Value & " Minuten"
Sheets("DVD").Cells(zeile, 5).Value = ComboBoxFSK.Value
Sheets("DVD").Cells(zeile, 6).Value = ComboBoxVerpackung.Value
End If
End Sub
***
Er bleibt allerdings immer bei der Startzeile (zeile = 4) hängen, für diese Zeile funktioniert es also. Wenn ich z.B. "test" eingebe, und OK drücke, übernimmt er den Datensatz. Drück ich erneut ok mit "test" als Titel, kommt die MsgBox und er macht weiter nichts. Geb ich aber dann "test2" ein, springt er natürlich in zeile = 5, schreibt es in die Tabelle. Beim erneuten klick auf OK, springt er hier aber in zeile = 6, da ich die Zählfunktion nicht in die Schleife eingebaut habe. Meine Frage ist also nur, WO ich die reinsetzen muss. Hab mMn schon alles versucht. Eine For-Schleife von bspw. zeile 4 bis 500 um das Ganze führt dazu, dass natürlich auch der Titel "test" in die Zeilen 4 bis 500 geschrieben wird.
Ich hoffe ihr könnt mir helfen.
Gruß, schmidt206
Antwort 1 von snailhouse
Hallo Schmidt 206,
ich bin zwar auch noch ein Anfänger in Sachen VBA, aber so müsste es klappen:
Gruß
Jürgen
ich bin zwar auch noch ein Anfänger in Sachen VBA, aber so müsste es klappen:
Private Sub CommandButtonOK_Click()
Dim zeile As Integer
Dim gefunden As Boolean
zeile = 4
gefunden = false
Do While zeile < 500 'Zeilenprüfung der Tabelle um Überschreiben zu verhindern
If TextBoxTitel.Value = Sheets("DVD").Cells(zeile, 1).Value Then 'Überprüfen, ob Titel schon vorhanden ist
MsgBox "Fehler! Eine DVD mit diesem Titel ist bereits vorhanden!"
Gefunden=True
Exit Do
End If
If Sheets("DVD").Cells(zeile, 1).Value = "" Then ' Verlässt die Schleife mit Nummer der leeren Zeile
Exit Do
Else: zeile = zeile + 1
End If
Loop
If gefunden = False Then
Sheets("DVD").Cells(zeile, 1).Value = TextBoxTitel.Value 'Übertragen in Tabelle
Sheets("DVD").Cells(zeile, 2).Value = ComboBoxJahr.Value
Sheets("DVD").Cells(zeile, 3).Value = ComboBoxDisks.Value
Sheets("DVD").Cells(zeile, 4).Value = TextBoxLaenge.Value & " Minuten"
Sheets("DVD").Cells(zeile, 5).Value = ComboBoxFSK.Value
Sheets("DVD").Cells(zeile, 6).Value = ComboBoxVerpackung.Value
End If
End Sub
Gruß
Jürgen
Antwort 2 von Marie
Mist, hier kann man wirklich jemandem wie Dir seinen Fehler kaum aufzeigen, weil der Code nicht eingerückt werden kann
:-(((((((((((((((((((((((
logisch:
zeile = 4
If TextBoxTitel.Value = Sheets("DVD").Cells(zeile, 1).Value Then
......MsgBox "DVD mit diesem Titel bereits vorhanden!"
Else
..........
End If
Du überprüfst, ob der Titel in Zeile 4 steht, wenn ja, dann bist Du fertig.
----------------------------------------------------------
Nun kommt der else-Teil:
steht Dein Titel nicht in Zeile 4, dann suchst Du die nächste leere Zeile und schreibst den Titel dort rein und zwar so oft Du auf den Button klickst.
Gibst Du Test 2 ein und klickst 50 mal auf den Button, dann schreibst du 50 mal untereinander den Titel Test2 immer in die nächste freie Zeile.
Das ist Deine Schleife im Elseteil, in der tust Du doch gar nix als raushüpfen, wenn Du ne leere Zelle findest, andernfalls weiterzählen bis 500:
Do While zeile < 500
If .....Value = "" Then Exit Do
Else: zeile = zeile + 1
End If
Loop
Und in diese Schleife kommst nur dann rein, wenn Du nicht den Text in Zeile 4 bereits stehen hast.
Du willst aber doch wohl zuerst alle 500 Zeilen durchsuchen, ob der Titel in Spalte 1 bereits vorhanden ist??? Wenn nein, dann erneut alle 500 Zeilen durchsuchen um die erste leere Zeile zu finden und den Titel dort einzutragen, dieser Teil klappt ja.
Dim zeile As Integer
zeile = 4
While zeile < 500
if TBTitel.Value = Sheets("DVD").Cells(zeile, 1).Value Then
...........MsgBox "Titel bereits vorhanden
...........exit Do
else
..zeile = zeile +1
endif
Wend
So durchläufst Du alle 500 Zeilen, wenn der Titel noch nicht existiert, dann hast Du keine Textbox erhalten und bist durchgelaufen bis 500. Wenn der Titel zum Beispiel in Zeile 128 bereits vorhanden ist, dann ist Der Wert Deiner Zeile jetzt 129!!
Also musst Du jetzt eine neue Schleife machen
if Zeile = 500 then
....
endif
-------------------------------------
In diese Schleife schreibst Du Deinen Code:
leere Zeile suchen und Titel eintragen, also:
Das Ganze sieht dann, beschissen unübersichtlich so aus:
Private Sub CommandButtonOK_Click()
Dim zeile As Integer
zeile = 4
Do While zeile < 500
If TextBoxTitel.Value = Sheets("DVD").Cells(zeile, 1).Value Then
MsgBox "bereits vorhanden!"
Exit Do
Else
zeile = zeile + 1
End If
Loop
If zeile = 500 Then ' Titel ist nicht vorhanden, muss eingetragen werden
zeile = 4
Do While zeile < 500 ' erste leere zeile finden
If Sheets("DVD").Cells(zeile, 1).Value = "" Then ' leere Zeile, Titel eintragen
Sheets("DVD").Cells(zeile, 1).Value = TextBoxTitel.Value 'Übertragen in Tabelle
Sheets("DVD").Cells(zeile, 2).Value = ComboBoxJahr.Value
Sheets("DVD").Cells(zeile, 3).Value = ComboBoxDisks.Value
Sheets("DVD").Cells(zeile, 4).Value = TextBoxLaenge.Value & " Minuten"
Sheets("DVD").Cells(zeile, 5).Value = ComboBoxFSK.Value
Sheets("DVD").Cells(zeile, 6).Value = ComboBoxVerpackung.Value
Exit Do
Else
zeile = zeile + 1 ' weitersuchen nach der ersten leeren Zeile
End If
Loop
End If
End Sub
:-(((((((((((((((((((((((
Zitat:
Er bleibt allerdings immer bei der Startzeile (zeile = 4) hängen
Er bleibt allerdings immer bei der Startzeile (zeile = 4) hängen
logisch:
zeile = 4
If TextBoxTitel.Value = Sheets("DVD").Cells(zeile, 1).Value Then
......MsgBox "DVD mit diesem Titel bereits vorhanden!"
Else
..........
End If
Du überprüfst, ob der Titel in Zeile 4 steht, wenn ja, dann bist Du fertig.
----------------------------------------------------------
Nun kommt der else-Teil:
steht Dein Titel nicht in Zeile 4, dann suchst Du die nächste leere Zeile und schreibst den Titel dort rein und zwar so oft Du auf den Button klickst.
Gibst Du Test 2 ein und klickst 50 mal auf den Button, dann schreibst du 50 mal untereinander den Titel Test2 immer in die nächste freie Zeile.
Zitat:
Do While zeile < 500
If Sheets("DVD").Cells(zeile, 1).Value = "" Then
Exit Do
Else: zeile = zeile + 1
End If
Loop
Do While zeile < 500
If Sheets("DVD").Cells(zeile, 1).Value = "" Then
Exit Do
Else: zeile = zeile + 1
End If
Loop
Das ist Deine Schleife im Elseteil, in der tust Du doch gar nix als raushüpfen, wenn Du ne leere Zelle findest, andernfalls weiterzählen bis 500:
Do While zeile < 500
If .....Value = "" Then Exit Do
Else: zeile = zeile + 1
End If
Loop
Und in diese Schleife kommst nur dann rein, wenn Du nicht den Text in Zeile 4 bereits stehen hast.
Du willst aber doch wohl zuerst alle 500 Zeilen durchsuchen, ob der Titel in Spalte 1 bereits vorhanden ist??? Wenn nein, dann erneut alle 500 Zeilen durchsuchen um die erste leere Zeile zu finden und den Titel dort einzutragen, dieser Teil klappt ja.
Dim zeile As Integer
zeile = 4
While zeile < 500
if TBTitel.Value = Sheets("DVD").Cells(zeile, 1).Value Then
...........MsgBox "Titel bereits vorhanden
...........exit Do
else
..zeile = zeile +1
endif
Wend
So durchläufst Du alle 500 Zeilen, wenn der Titel noch nicht existiert, dann hast Du keine Textbox erhalten und bist durchgelaufen bis 500. Wenn der Titel zum Beispiel in Zeile 128 bereits vorhanden ist, dann ist Der Wert Deiner Zeile jetzt 129!!
Also musst Du jetzt eine neue Schleife machen
if Zeile = 500 then
....
endif
-------------------------------------
In diese Schleife schreibst Du Deinen Code:
leere Zeile suchen und Titel eintragen, also:
Das Ganze sieht dann, beschissen unübersichtlich so aus:
Private Sub CommandButtonOK_Click()
Dim zeile As Integer
zeile = 4
Do While zeile < 500
If TextBoxTitel.Value = Sheets("DVD").Cells(zeile, 1).Value Then
MsgBox "bereits vorhanden!"
Exit Do
Else
zeile = zeile + 1
End If
Loop
If zeile = 500 Then ' Titel ist nicht vorhanden, muss eingetragen werden
zeile = 4
Do While zeile < 500 ' erste leere zeile finden
If Sheets("DVD").Cells(zeile, 1).Value = "" Then ' leere Zeile, Titel eintragen
Sheets("DVD").Cells(zeile, 1).Value = TextBoxTitel.Value 'Übertragen in Tabelle
Sheets("DVD").Cells(zeile, 2).Value = ComboBoxJahr.Value
Sheets("DVD").Cells(zeile, 3).Value = ComboBoxDisks.Value
Sheets("DVD").Cells(zeile, 4).Value = TextBoxLaenge.Value & " Minuten"
Sheets("DVD").Cells(zeile, 5).Value = ComboBoxFSK.Value
Sheets("DVD").Cells(zeile, 6).Value = ComboBoxVerpackung.Value
Exit Do
Else
zeile = zeile + 1 ' weitersuchen nach der ersten leeren Zeile
End If
Loop
End If
End Sub
Antwort 3 von gast123
hi all
eine false zuweisung ist in diesem falle unnoetig da der defaultwert ja false ist
eine schrittweise abarbeitung im vbed mit kontrolle der variablen haette wunder gewirkt und den fragesteller schnell aufgeklaert ueber seine fehler
gruss gast123
eine false zuweisung ist in diesem falle unnoetig da der defaultwert ja false ist
eine schrittweise abarbeitung im vbed mit kontrolle der variablen haette wunder gewirkt und den fragesteller schnell aufgeklaert ueber seine fehler
gruss gast123
Antwort 4 von schmidt206
Vielen Dank - funktioniert!
Jetzt hab ich noch ein anderes Problem:
Ich habe ganz links noch eine Spalte eingefügt, alles soweit geändert. Die Spalte heißt "ID" und fügt jedem neuen Datensatz eine Nummer zu, die folgendermaßen gebildet wird:
[QUOTE]
Sheets("DVD").Cells(zeile, 1).Value = (zeile - 3)
[/QUOTE]
Das funktioniert ohne Probleme, da ich in Zeile 4 anfange, er also bei Nr. 1 anfängt. Das Problem bekomme ich, wenn ich meinen Button zum Löschen eines Datensatzes klicke:
[QUOTE]
Private Sub CommandButtonDelDatensatz_Click()
Dim i As Integer
Dim aktzeileStr As String
Dim aktzeileInt As Integer
Dim aktzeileID As Integer
zeile = 4
Do While zeile < 500 'Suchen des Datensatzes
If Sheets("DVD").Cells(zeile, 2).Value = ComboBoxDatensatz.Value Then
Exit Do
Else: zeile = zeile + 1
End If
Loop
If Sheets("DVD").Cells(zeile + 1, 1).Value <> "" Then 'Prüfen, ob nächste Zeile leer ist
Rows(zeile).EntireRow.Delete 'Zeile löschen
Sheets("DVD").Cells(zeile, 1).Value = ""
aktzeileStr = ActiveCell.Address
aktzeileInt = CInt(aktzeileStr)
aktzeileID = aktzeileInt - 3
Sheets("DVD").Cells(zeile, 1).Value = (aktzeileID - 3)
Else: Rows(zeile).EntireRow.Delete
End If
ComboBoxDatensatz.Clear
zeileX = 4
Do While zeileX < 500 'Datensätze zur ComboBoxDatensatz hinzufügen
If Sheets("DVD").Cells(zeileX, 2).Value <> "" Then
ComboBoxDatensatz.AddItem Sheets("DVD").Cells(zeileX, 2)
zeileX = zeileX + 1
Else: Exit Do
End If
Loop
End Sub
[/QUOTE]
Dazu muss ich sagen, dass ich vorher bei jeder Aktion alle aktuellen Datensätze in die "ComboBoxDatensatz" einfügen lasse. Er prüft also beim Klicken des Knopfes, ob die aktuelle Zeile in der Tabelle dem Datensatz aus der ComboBoxDatensatz entspricht, springt ansonsten weiter, bis er diese gefunden hat. Bis dahin gibts keine Probleme. Wenn er jedoch die Zeile lösche (EntireRow.Delete), gibts Komplikationen mit der Spalte "ID", die natürlich dann aktualisiert werden muss, damit da nicht "2" und danach "4" steht, er die also aktualisiert. Habs versuch mit der Funktion "ActiveCell", da hat er allerdings Probleme bei "aktzeileInt = CInt(aktzeileStr)" und führt es nicht weiter aus, was ich nicht ganz verstehe. Habt ihr ne Idee?
Gruß, schmidt206
Jetzt hab ich noch ein anderes Problem:
Ich habe ganz links noch eine Spalte eingefügt, alles soweit geändert. Die Spalte heißt "ID" und fügt jedem neuen Datensatz eine Nummer zu, die folgendermaßen gebildet wird:
[QUOTE]
Sheets("DVD").Cells(zeile, 1).Value = (zeile - 3)
[/QUOTE]
Das funktioniert ohne Probleme, da ich in Zeile 4 anfange, er also bei Nr. 1 anfängt. Das Problem bekomme ich, wenn ich meinen Button zum Löschen eines Datensatzes klicke:
[QUOTE]
Private Sub CommandButtonDelDatensatz_Click()
Dim i As Integer
Dim aktzeileStr As String
Dim aktzeileInt As Integer
Dim aktzeileID As Integer
zeile = 4
Do While zeile < 500 'Suchen des Datensatzes
If Sheets("DVD").Cells(zeile, 2).Value = ComboBoxDatensatz.Value Then
Exit Do
Else: zeile = zeile + 1
End If
Loop
If Sheets("DVD").Cells(zeile + 1, 1).Value <> "" Then 'Prüfen, ob nächste Zeile leer ist
Rows(zeile).EntireRow.Delete 'Zeile löschen
Sheets("DVD").Cells(zeile, 1).Value = ""
aktzeileStr = ActiveCell.Address
aktzeileInt = CInt(aktzeileStr)
aktzeileID = aktzeileInt - 3
Sheets("DVD").Cells(zeile, 1).Value = (aktzeileID - 3)
Else: Rows(zeile).EntireRow.Delete
End If
ComboBoxDatensatz.Clear
zeileX = 4
Do While zeileX < 500 'Datensätze zur ComboBoxDatensatz hinzufügen
If Sheets("DVD").Cells(zeileX, 2).Value <> "" Then
ComboBoxDatensatz.AddItem Sheets("DVD").Cells(zeileX, 2)
zeileX = zeileX + 1
Else: Exit Do
End If
Loop
End Sub
[/QUOTE]
Dazu muss ich sagen, dass ich vorher bei jeder Aktion alle aktuellen Datensätze in die "ComboBoxDatensatz" einfügen lasse. Er prüft also beim Klicken des Knopfes, ob die aktuelle Zeile in der Tabelle dem Datensatz aus der ComboBoxDatensatz entspricht, springt ansonsten weiter, bis er diese gefunden hat. Bis dahin gibts keine Probleme. Wenn er jedoch die Zeile lösche (EntireRow.Delete), gibts Komplikationen mit der Spalte "ID", die natürlich dann aktualisiert werden muss, damit da nicht "2" und danach "4" steht, er die also aktualisiert. Habs versuch mit der Funktion "ActiveCell", da hat er allerdings Probleme bei "aktzeileInt = CInt(aktzeileStr)" und führt es nicht weiter aus, was ich nicht ganz verstehe. Habt ihr ne Idee?
Gruß, schmidt206