VBA Zeile löschen, Fehler in der Schleife?

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.

Woher ich das weiß:Berufserfahrung – Programmierer
Suboptimierer  16.08.2021, 11:04

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.

0
TygaX 
Fragesteller
 16.08.2021, 15:48

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

0
Suboptimierer  16.08.2021, 15:51
@TygaX

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.

0
TygaX 
Fragesteller
 16.08.2021, 15:52
@Suboptimierer

Hört sich alles plausibel an, allerdings kann ich sowas gar nicht schreiben

0

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.

TygaX 
Fragesteller
 16.08.2021, 15:50

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

0
daCypher  16.08.2021, 16:16
@TygaX

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
0
TygaX 
Fragesteller
 16.08.2021, 16:02

Jetzt bekomme ich Fehler in der Zeile die du mir genannt hast:

UsedRange.SpecialCells(xlCellTypeLastCell).EntireRow.Delete
0
daCypher  16.08.2021, 16:17
@TygaX

Welche Fehlermeldung kommt denn? Einfach nur "Es kommt ein Fehler" reicht nicht, um die Ursache zu finden.

0
TygaX 
Fragesteller
 16.08.2021, 16:19
@daCypher

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

0
daCypher  16.08.2021, 16:39
@TygaX

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.

0
TygaX 
Fragesteller
 16.08.2021, 16:47
@daCypher

Danke dir!!! Echt ich danke dir vielmals. Dein zweiter Punkt wars. Jetzt funktioniert alles.

0

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.