Letzte Zeile und letzte Spalte mit VBA ermitteln

Bezogen auf den Beitrag "For"-Loop in VBA kam von einem Leser die Frage, ob das Makro später hinzugefügte Einträge automatisch berücksichtigen kann. In der angesprochenen Schleife (Loop) haben wir einen Vorgang X-mal wiederholt. In diesem Beitrag werden wir nun die letzte Zeile der aktuellen Tabelle durch ein Makro selbst ermitteln lassen, damit die Anzahl der vorzunehmenden Vorgänge automatisch bestimmt wird.  Ich verwende hier die gleiche Beispieltabelle wie bereits für den "For"-Loop:

Beispieldatei

Die letzte Zeile ist also die 7 und unser Ziel ist es, in Spalte B "männlich" oder "weiblich" zu erhalten - je nach Eintrag in Spalte A.

Unser "For"-Loop besteht in dem Fall aus nachfolgenden Code-Zeilen:

For x = 2 To 7
If Cells(x, 1) = "M" Then
Cells(x, 2) = "Männlich"
End If
If Cells(x, 1) = "W" Then
Cells(x, 2) = "Weiblich"
End If
Next

Die Anzahl Wiederholungen der Schleife wurden mittels "For x = 2 To 7" angegeben - also von Zeile 2 bis 7.

Wenn wir jedoch im Laufe der Zeit weitere Werte erfassen, müssten wir auch die "7" in unserem Code anpassen. Hier kommt die Ermittlung der letzten Zeile ins Spiel. Mit diesem Befehl kannst Du die letzte Zeile der Spalte A im aktuellen Tabellenblatt ermitteln:

ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row

Die letzte Zeile muss jedoch als Variable definiert werden. Nennen wir sie "LetzteZeile". Der vollständige Befehl in VBA zur Ermittlung der letzten Zeile lautet demzufolge:

LetzteZeile = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row

Wenn Du nun vor Deinem Loop diese Codezeile stehen hast, kannst Du die Anzahl Wiederholungen mit der Variable "LetzteZeile" angeben:

For x = 2 to LetzteZeile

Erfasse nun einmal weitere Daten in Deiner Excel-Tabelle und teste Dein Makro erneut. Führe den Code auch einmal mit "F8" Schritt für Schritt aus. Wenn Du dann mit der Maus über "LetzteZeile" oder auch über "x" stehen bleibst, siehst Du, was der aktuelle Wert für diese Variablen ist:

MouseHoover

Um die letzte Spalte (beispielsweise in Zeile 1) zu ermitteln, lautet der Befehl wie folgt:

LetzteSpalte = Cells(1, Columns.Count).End(xlToLeft).Column

Solche Variablen zu setzten erlaubt es Dir, Deine Excel-Tabellen viel dynamischer zu gestalten, sodass Deine Makros direkt auf neue Einträge reagieren und Du den effektiven Bereich nicht mehr selbst anpassen musst. Gerade bei komplexeren Programmen wird es immer schwieriger, den Überblick zu behalten und sämtliche solche Bereiche von Hand anzupassen. Hast Du konkrete Anwendungsbeispiele oder Fragen zu diesen Themen? Lass es mich doch in den Kommentaren wissen oder schreib mir via Kontaktformular - ich würde mich freuen, weitere spezifische Anliegen zu behandeln!

Suchmaschine programmieren

Sobald eine Excel-Tabelle viele Einträge hat, sind Filter beinahe unumgänglich. Man kann einzelne Begriffe selbstverständlich rasch mittels der Such-Funktion "CTRL + F" finden. Wir wollen hier jedoch in VBA unsere eigene Suchmaschine programmieren, um wiederkehrend unsere Datenbank nach einem gewünschten Suchkriterium zu durchsuchen. Unser fertiges Produkt soll somit nur diejenigen Zeilen anzeigen, welche auch dieses Kriterium enthalten. In diesem Beitrag programmieren wir eine solche Suchmaschine für folgende Musik-Datenbank:

Datenbank

Vorbereitungsschritte

Wir fügen nun oberhalb der Überschrift eine neue Zeile 1 ein. In "A1" schreiben wir "Suchkriterium:" und die Zelle "B1" markieren wir farbig - dort soll jeweils unser Suchbegriff eingegeben werden. In "C1" fügen wir ein Textfeld ein und schreiben "Suche starten!" - dies wird unser Button, um das Makro später auszulösen. Damit unser Filter auf das Suchkriterium abgestimmt werden kann, müssen wir in Spalte D die nachfolgende Formel einsetzen. Für die Zeile Nummer 3 (Zelle "D3") lautet diese für's Erste:

=WVERWEIS($B$1;A3:C3;1;FALSCH)

Du kannst nun einmal einen Suchbegriff eingeben und das Resultat für die Formel "WVERWEIS(...)" betrachten:

WVERWEIS

Ich empfehle Dir, die Suchbegriffe jeweils mit Sternchen (*) einzugeben, damit Du sicher alle Resultate angezeigt bekommst, welche den Begriff enthalten.

Die Formel "WVERWEIS(...)" müssen wir noch leicht anpassen, um den Filter besser anwenden zu können. Wir wenden hierzu zusätzlich die Formel "WENNFEHLER" und schreiben:

=WENNFEHLER(WVERWEIS($B$1;A3:C3;1;FALSCH);0)

Du siehst nun: Überall, wo vorhin "#NV" war, steht nun "0". Die Fehlermeldung "#NV" hatte uns lediglich angezeigt, dass in der entsprechenden Zeile nichts dem Suchkriterium entspricht. Die "0" wird für uns im Makro jedoch viel einfacher auszugrenzen sein.

Automatisch filtern mit VBA

Wir setzen nun den Filter auf Zeile zwei (unsere Überschrift) und beginnen, ein Makro aufzuzeichnen. Sobald der Rekorder gestartet ist, filtern wir sämtliche "0" heraus und stoppen die Aufnahme bereits wieder. Folgender Code wurde in der Zwischenzeit aufgezeichnet:

ActiveSheet.Range("$A$2:$D$8").AutoFilter Field:=4, Criteria1:="Pop"

Allerdings entspricht dies nicht ganz dem, was wir eigentlich wollten. Die Intention war es ja, alle "0" auszufiltern. Deshalb müssen wir den letzten Teil des Filterkriteriums ("Criteria1:="Pop") anpassen zu:

Criteria1:="<>0"

Wir können nun ein anderes Suchkriterium eingeben und unser Makro ausführen - es funktioniert wie gewünscht! Zuletzt können wir das Makro unserem Textfeld ("Suche starten!") zuweisen. Mittels Rechtsklick auf das Textfeld → "Makro zuweisen" kannst Du dein zuvor aufgezeichnetes Makro selektieren.

"Message-Box" über die Anzahl Treffer

Nehmen wir uns noch zwei ästhetischen Punkten an: Wir können die Spalte D problemlos ausblenden, das Makro wird nach wie vor funktionieren. Desweiteren möchten wir eine "Message-Box" einrichten, die uns jeweils die Anzahl der gefundenen Treffer angibt. Wir geben eine weitere Codezeile ein:

AnzahlTreffer = Application.WorksheetFunction.Subtotal(3, Range("A:A"))-2

Die Variable "AnzahlTreffer" umfasst das Resultat der Funktion "TEILERGEBNIS" unter der Verwendung von "ANZAHL2". Wir subtrahieren "2", um die beschriebenen Felder "A1" und "A2" abzuziehen. Nun können wir die nächste Codezeile einfügen:

MsgBox ("Insgesamt " & AnzahlTreffer & " Treffer gefunden.")

 ... und dies ist unser Resultat:

 MsgBox

Bereich eines Namens automatisch erweitern

Wir haben uns bereits den Namensmanager und die Dropdown-Listen angeschaut. Wenn Du zu der Kriterienliste weitere Begriffe hinzufügst, wird der Bereich Deines Namens allerdings nicht automatisch erweitert - Du musst via Namensmanager die letzte Zelle manuell angeben, respektive den effektiven Bereich neu selektieren. Mit der Formel "BEREICH.VERSCHIEBEN" kann dieser Schritt automatisiert werden. Excel sagt uns folgendes über diese Formel:

Gibt einen Bezug zurück, der gegenüber dem angegebenen Bezug versetzt ist.

Man kann damit nicht nur den Bereich "A1:A3" nach "A3:A5" verschieben, sondern auch auf "A1:A5" erweitern - und genau das wollen wir in diesem Beitrag thematisieren. Schauen wir uns einmal die Syntax der Formel an:

BEREICH.VERSCHIEBEN(Bezug; Zeilen; Spalten; [Höhe]; [Breite])

Wir beginnen also mit einem Bezug - einer einzelnen Zelle (A1). "Zeilen" und "Spalten" stehen jeweils für eine Verschiebung um X Zellen nach unten respektive nach rechts. "[Höhe]" und "[Breite]" hingegen lässt uns einen Bereich nach unten oder nach rechts erweitern. Mithilfe der Formel "ANZAHL2" als "Höhe" kannst Du zählen, wie viele Argumente in einer Spalte stehen und so die Anzahl Zellen Deines Bereiches ermitteln. Die Formel lautet demnach:

=BEREICH.VERSCHIEBEN($A$1;;;ANZAHL2(A:A);)

Wir setzen A1 absolut ($), weil diese Formel als Namen definiert werden soll. Der Name ist in einem Tabellenblatt oder einer gesamten Excel-Arbeitsmappe vorhanden. Ohne die Dollarzeichen würde sich deshalb in anderen Zellen die Referenz automatisch verschoben werden und nicht an A1 festhalten. Beachte anschliessend die nacheinanderfolgenden Semikolon (;) - wir geben weder bei "Zeilen" noch bei "Spalten" etwas ein - die ANZAHL2-Formel ermittelt die Höhe unseres Bereiches anhand sämtlicher nichtleerer Zellen in Spalte A.

Die obengenannte Formel musst Du bei Deinem Namen als Bezug eingeben, um die Kriterien nachher in Deiner Dropdown-Liste aufzuführen (siehe "Namensmanager" und "Dropdown-Liste"). Klicke hierfür auf den Menüpunkt "Formeln" → "Namen definieren". Der Bezug "$A$1" wird Dir automatisch mit dem Namen des entsprechenden Tabellenblattes ergänzt (bspw. Tabelle1!$A$1). Bitte beachte deshalb folgendes, wenn Du auf andere Tabellenblätter Bezug nehmen musst: Falls Du Deine Kriterien zum Beispiel im separaten Tabellenblatt "Parameter" hast, heissen Deine Bezüge "Parameter!$A$1" und "Parameter!A:A".

Wenn wir nun ein neues Kriterium zu unserer Liste hinzufügen, wird dies automatisch zum Namen und folglich in die Dropdown-Liste mitaufgenommen.