Hilfe zur Selbsthilfe
Hi tausendschön,
deine Ideen waren doch schon recht richtig.
Ich habe dir hier den Makro nochmal mit ausführlichen Kommentaren gespickt. Ich denke, damit fällt das Verstehen leichter.
Gruß, Andreas
Private Sub Worksheet\_Change(ByVal Target As Range)
' Der Name Worksheet\_Change wird von VBA vergeben. Es ist die Ereignis-Routine,
' die immer dann automatisch aufgerufen wird, wenn sich auf dem Tabellenblatt,
' in dessen Codebereich sie steht, etwas an den Zellinhalten ändert.
' Die Variable Target stellt den Zellenbereich dar, in dem sich etwas geändert hat.
If Target.Column 4 Then Exit Sub
' Wenn die Spalte in der Target steht ungleich 4 ist (also ungleich Spalte D ist),
' wird die Routine gleich wieder beendet.
If Left(LCase(Target.Value), 11) = "wegfall zum" Then
' Target steht also jetzt in Spalte D.
' Es wird getestet, welchen Inhalt die geäderte Zelle hat:
' Target.Value ist der gesamte Inhalt
' Lcase macht aus allen Großbuchstaben Kleinbuchstaben.
' Eine Vorsichtgsmaßnahme, falls dir beim Tippen sowas wie "WEgfall" passiert
' Left(..., 11) holt sich nur die linken 11 Zeichen des gesamten (durch LCase
' kleingeschriebenen) Inhalts.
With Worksheets("Wegfälle")
' Wenn zwischen den Zeilen With und End With ein Objektbezeichner mit einem Punkt
' begonnen wird, bezieht sich dieses Objekt auf dasjenige in der With-Zeile.
' Das kann viel Schreibarbeit sparen, wenn man sich auf Unter-Unter...Objekte bezieht
.Rows(.Cells(.Rows.Count, 1).End(xlUp).Row + 1).Value = Rows(Target.Row).Value
' Jetzt werden die Daten kopiert.
' Rechts vom Gleichheitszeichen steht, wo sie herkommen:
' Target.Row ist die Zeilennummer der gänderten Zelle.
' Rows(Target.Row) ist also die gesamte Zeile.
' Rows(Target.Row).Value sind die Inhalte der Zellen in der Zeile
' Links vom Gleichheitszeichen steht, wo die Daten hin sollen.
' Da der Datenursprung eine ganze Zeile ist, muss das Ziel auch eine
' ganze Zeile sein.
' Es soll die erste freie Zeile von oben benutzt werden.
' .Rows bezieht sich nun auf eine Zeile im Blatt "Wegfälle" (siehe With-Anweisung).
' Jetzt kommt eine etwas verschrobene (aber sehr sinnvolle) "Berechnung",
' in welche Zeile die Daten sollen:
' .Rows.Count ist die maximale Anzahl der Zeilen im Blatt "Wegfälle".
' Wohlgemerkt, nicht die gefüllten Zeilen ,sondern alle (möglichen).
' Da die maximale Zeilenzahl bei verschiedenen Excel-Versionen verschieden ist,
' benutzt man keine feste Zahl, sondern .Rows.Count, um flexibel zu sein.
' .Cells(.Rows.Count, 1) ist also die Zelle in Spalte A (die 1 in der Klammer)
' und in der allerletzten möglichen Zeile.
' .End(xlUp) ist so viel wie das Drücken von Strg+Pfeil nach Oben.
' Wir suchen also von der allerletzten Zelle in Spalte A aus die erste Zelle darüber,
' die nicht leer ist.
' .Row ist die Zeilennummer dieser Zelle.
' Dies ist also die letzte belegte Zelle. Mit +1 kommen wir in die erste freie.
' Warum dieser Umweg des Von-Unten-Schauens?
' Es könnte ja sein, dass zwischen den gefüllte Zeilen irgendwo Leerzeilen sind.
' Sucht man von oben und findet eine Leere Zeile, weiß man nicht ob noch gefüllte kommen.
End With
' Wurde oben erklärt.
Application.EnableEvents = False
' Wir wollen jetzt gleich die Zeile im Eingabeblatt löschen.
' Das ist aber auch eine Veränderung des Blattinhaltes.
' Damit sich die Routine dabei nicht wieder selbst aufruft,
' deaktivieren wir die Reaktion von VBA auf Ereignisse
' für den nächsten Schritt.
Rows(Target.Row).Delete xlUp
' Rows (Objektbezeichner ohne Punkt) bezieht sich immer auf das aktive Blatt)
' Target.Row ist wieder die Zeilennummer der geänderten Zelle,
' also ist Rows(Target.Row) die gesamte Zeile.
' Delete löscht dise Zeile
' xlUp gibt an, dass die nachfolgenden Zeilen nach oben geschoben werden sollen.
' Ich hab's nicht getestet, aber ich glaube, man könnte das weglassen.
' Was soll auch sonst mit nachfolgenden Zeile passieren?
Application.EnableEvents = True
' Reaktion auf Ereignisse wird wieder eingeschaltet.
End If
' All das ist nur passiert, wenn ... siehe oben.
End Sub
' Feddisch