VBA Zeile löschen, Fehler in der Schleife?
Ich habe die Variable a formuliert und diese auf True gesetzt, nun soll wenn in einer Textbox keine nummerischen Zeichen eingetragen werden, die letzte Zeile gelöscht werden. In meinem Makro habe ich noch weitere Bedingungen formuliert, die dasselbe bereits tun, allerdings jetzt bei der Variable bekomme ich nur Fehler raus.
3 Antworten
Da du bei a = False nur die letzte Zeile gelöscht haben willst, würde ich deine For-Schleife so lassen, wie sie war (ohne "Or a = False"). Die Verwurstung von a würde ich vor die Schleife ziehen.
If not a Then _
Rows(lz).Delete shift:= xlUp
Kleiner Hinweis zum Löschen von Zeilen innerhalb von Schleifen:
Ich habe es bei dir nicht überprüft, aber man muss höllisch aufpassen, dass man alles löscht, was man löschen will, denn mit jedem Löschvorgang reduziert sich die Zeilenzahl. Unter Umständen löscht man über den Rand hinaus oder es werden zu prüfende Zeilen übersprungen.
Falls dieses Phänomen bei dir auftreten sollte, empfehle ich eine Schleife vorzuschalten, in der du alle zu löschenden Zeilen markierst / dir merkst und im zweiten Schritt alle markierten Zeilen löschst.
Alternative zur Markierung zu löschender Datensätze ist, dass du eine Löschfunktion schreibst und diese solange aufrufst, bis nichts mehr gelöscht wurde. Das bedeutet, die Funktion wird genau einmal zuviel aufgerufen und es wird jedesmal von vorne gesucht.
Dafür ist dieser Weg sehr komfortabel.
Hört sich alles plausibel an, allerdings kann ich sowas gar nicht schreiben
Und noch ein Hinweis: a ist ein bescheidener Name für eine Variable. Besser wäre es, wenn man direkt ablesen könnte, dass a True ist, wenn der Wert numerisch ist.
Ich glaub, du musst etwas genauer erklären, was du gebaut hast und was du machen willst.
Also du hast eine Textbox mit dem Namen "Wert" und wenn da keine Zahl eingetragen wurde (inkl. wenn garnichts eingetragen wurde) soll die letzte Zeile aus deiner Excel gelöscht werden?
Im Moment ist der Code so, dass dann alle Zeilen gelöscht werden, bei denen in den Spalten A oder B nichts drin steht.
Wenn einfach immer die letzte Zeile gelöscht werden soll, wenn in Wert nichts drin steht, geht das so:
If Not IsNumeric(Wert) Or Wert = "" Then
UsedRange.SpecialCells(xlCellTypeLastCell).EntireRow.Delete
End If
Wenn stattdessen alle Zeilen gelöscht werden sollen, in denen in A oder B nichts steht, kannst du es damit machen:
If Not IsNumeric(Wert) Or Wert = "" Then
On Error Resume Next ' Fehler "Keine Zellen gefunden" deaktivieren
Intersect(UsedRange, Range("A:B")).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
On Error GoTo 0
End If
Damit verhinderst du auch unerwünschte Effekte, wenn du versuchst, auf Zeilen zuzugreifen, die du grade gelöscht hast.
Jetzt bekomme ich Fehler in der Zeile die du mir genannt hast:
UsedRange.SpecialCells(xlCellTypeLastCell).EntireRow.Delete
Also das ist mein ganzer Sub
Private Sub Hinzufügen_Click()
'Aktuelles Jahr dem auswählbaren Monat automatisch hinzuügen
Dim AktuellesJahr As Long
AktuellesJahr = Year(Now)
'Eintragung eingestellter Werte durch Maske
Dim i As Double
With Application.ActiveSheet
i = .Cells(.Rows.Count, "A").End(xlUp).Row
j = i + 1
End With
Cells(j, 1) = Monat.Text & ", " & AktuellesJahr
Cells(j, 2) = Referenz.Value
'Eingabe für Option Einnahmen eintragen
If EinnahmenOption = True Then
Cells(j, 3) = Wert.Value
End If
'Eingabe für Option Ausgaben eintragen
If AusgabenOption = True Then
Cells(j, 4) = Wert.Value
End If
'Keine Auswahl bzw. Eintragung, dann soll die durch vorherige Schritte leere Zeile gelöscht werden
If Monat.Text = "" Or Referenz.Text = "" Then
UsedRange.SpecialCells(xlCellTypeLastCell).EntireRow.Delete
End If
'Keine nummerische Eintragung, dann soll die durch vorherige Schritte leere Zeile gelöscht werden
If Not IsNumeric(Wert) Or Wert = "" Then
UsedRange.SpecialCells(xlCellTypeLastCell).EntireRow.Delete
End If
'Hinweis-Box bei fehlenden Angaben
Dim Ausführen As Boolean
Ausführen = True
If Monat.Text = "" Then Ausführen = False
If Referenz.Text = "" Then Ausführen = False
If Wert.Text = "" Then Ausführen = False
If Ausführen Then
Else
MsgBox "Bitte alle Felder vollständig ausfüllen."
End If
End Sub
Jetzt bekomme ich da halt immer einen Laufzeitfehler 424
Ein paar Dinge die mir dazu im Kopf rumschwirren:
- Du brauchst doch gar nicht erst aufwändig die letzte Zeile suchen, weil du doch die Zeile, die grade angelegt wurde in der Variable j hast. Also du kannst einfach Rows(j).Delete schreiben.
- Normalerweise macht man die nötigen Prüfungen vorher. Also anstatt eine neue Zeile zu füllen und am Ende zu prüfen, ob alles richtig ausgefüllt wurde (und dann die neu angelegte Zeile zu löschen), kannst du doch am Anfang schon prüfen, ob alles ok ist und im Zweifelsfall einfach keine neue Zeile anlegen.
- Wo hast du den Code reingeschrieben? Wenn er im Modul für die Tabelle steht, hast du mit Monat.Text und Referenz.Value keinen Zugriff auf die Elemente von deinem UserForm. Wenn der Code im Modul für das UserForm steht, hast du mit z.B. Cells(j, 1) oder UsedRange keinen Zugriff auf die Zellen der Tabelle, bzw. musst überall mit angeben, auf welches Tabellenblatt du dich beziehst (z.B. ActiveSheet.Cells... oder Sheets(1).Cells... oder Sheets("Tabelle1").Cells...
Der Laufzeitfehler 424 (mit der Fehlermeldung "Objekt erforderlich" kann man übrigens mehr anfangen, als mit der nackten Zahl) bedeutet normalerweise, dass du versuchst, eine Objektvariable zu benutzen, der noch kein Objekt zugewiesen wurde. Bzw. in diesem Fall, dass er mit Cells oder mit UsedRange nichts anfangen kann, weil es für Formularmodul halt keinen UsedRange gibt.
Also gemeint ist, es soll die letzte Zeile gelöscht werden sobald in Spalte A und /oder B nichts steht und/ oder sobald "Wert" nichts beträgt oder keine nummerische Zahl ist
Ok, also sobald irgendwo in Spalte A oder B nichts drin steht, sollen so lange Spalten von unten gelöscht werden, bis es nicht mehr so ist?
Oder anders ausgedrückt: Es soll alles gelöscht werden, was unter der letzten Zeile ist, in der A und B gefüllt sind?
Das wäre dann so:
If Not IsNumeric(Wert) Or Wert = "" Then
Range(Range("A:B").SpecialCells(xlCellTypeBlanks).Item(1).Row & ":" & UsedRange.SpecialCells(xlCellTypeLastCell).Row).EntireRow.Delete
End If
Ich gehe davon aus dass dies "lz" in manchen Fällen eine Zeile ermittelt hat die zum Fehler führt.
Nahezu alle Varianten die letzte Zeile zu ermitteln haben unter bestimmten Umständen die falsche Zeile ermittelt.
Daher gilt es vorbereitend vor der gewählten Methode die Fälle zu kennen und zu umgehen.
Z.B:
.End(xlUp) darf NICHT auf gefilterte (Zeilen nicht sichtbar) angewandt werden.
Jaa genau. Du beschreibst es exakt wie es bei mir ist :D
Allerdings fällt es mir echt schwer da eine Lösung zu finden