VBA - Meldungen (Display Alerts) automatisch umgehen

Makros können alle denkbaren Befehle ausführen – und sogar noch mehr. Auch wenn Du beispielsweise in Excel ein Tabellenblatt löschen möchtest, wirst Du gefragt, ob Du dies tatsächlich tun willst:

DisplayAlert

Um diese Meldungen (sogenannte Display Alerts) zu umgehen/zu überspringen, helfen zwei Codezeilen:

Application.DisplayAlerts=False

Application.DisplayAlerts=True

Am besten fügst Du diese beiden Zeilen exakt vor und nach dem entsprechenden Befehl ein:

Application.DisplayAlerts = False

Sheets("Tabelle1").Delete

Application.DisplayAlerts = True

Dadurch schränkst Du auch ein, dass sonstige mächtige Befehle ohne Dein Wissen und Deiner ausdrücklichen Bestätigung ausgeführt werden.

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

"For"-Loop in VBA

Bei Makros kann man jeden Befehl einzeln programmieren oder aufzeichnen. In einer ersten Einführung in die VBA-Umgebung habe ich Dir gezeigt, wie Du mit dem Makro-Rekorder arbeiten kannst und schnell zu mehr Code kommst. Sich wiederholende Befehle kann man selbstverständlich alle einzeln in Code schreiben. Es ist jedoch deutlich übersichtlicher, wenn Du Wiederholungen mit sogenannten Loops (Schleifen) programmierst. In diesem Beitrag möchte ich Dir die "For"-Schleife zeigen.

Mit diesem Loop kannst Du einen Befehl x-beliebig ausführen lassen. Mit dem nachfolgenden Code wird im Bereich A1:A10 jeweils "Mein erster Loop" geschrieben:

For x = 1 To 10
Cells(x, 1) = "Mein erster Loop"
Next

Betrachten wir die einzelnen Bestandteile genauer: Der Loop beginnt mit "For". Danach verwenden wir X als Variable, beginnend bei 1 bis 10. In der zweiten Code-Zeile verwenden wir "Cells" - also Zelle. In Zelle "x, 1" soll unser Text geschrieben werden. Wichtig zu beachten ist, dass in "Cells" die Reihenfolge gegenüber Excel umgekehrt ist - es beginnt hier mit der Zeile (Row), danach wird erst nach der Spalte (Column) gefragt. In Excel ist zuerst die Spalte und dann die Zeile anzugeben (beispielsweise A1). Der Befehl "Next" erweitert das X um eins und die Schlaufe wird erneut durchlaufen. Probier es mal aus und führe Dein Makro mit F8 Schritt für Schritt aus. Du kannst mit dem Cursor auf X bleiben, dann zeigt es Dir jeweils den aktuellen Wert der Variable an. Zu Beginn ist dies "x = Leer", danach nimmt es die Werte 1 bis 10 an.

Weitere Anwendungsbereiche

Abhängig von Deinem spezifischen Makro kann diese For-Schleife in unterschiedlicher Form zur Anwendung kommen. Im ersten Beispiel oben hast Du Dich auf die Zeile bezogen. Dasselbe funktioniert natürlich auch mit der Spalte [Cells(1, x)]. Eine weitere Möglichkeit besteht darin, eine Zelle auf dessen Wert zu überprüfen. In der nachfolgenden Datenbank soll das Geschlecht jeweils ausgeschrieben werden (W = Weiblich; M = Männlich).

For-Schleife

Dazu schreiben wir folgenden Code:

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 For-Schleife beginnt diesmal bei X = 2. Danach findet eine Überprüfung mittels "If-Then" statt. Pro Durchlauf habe ich jeweils nach "M" und anschliessend nach "W" gesucht - einfacher wäre die Verwendung von "If-Then-Else", also "Wenn-Dann-Sonst". Ich decke diesen Fall nicht in diesem Beitrag ab, Du kannst das aber gerne selbst ausprobieren!

Den letzten Fall, den ich noch aufzeigen möchte, ist das Entfernen von Zeilen. Nehmen wir an, wir möchten nur die weiblichen Personen angezeigt haben. Unsere Überprüfung soll also nach "M" suchen und in dem Fall die gesamte Zeile entfernen. Der Code dazu lautet wie folgt:

For x = 2 To 7
If Cells(x, 1) = "M" Then
Rows(Cells(x, 1).Row).Delete
x = x - 1
End If
Next

Der Check in den ersten beiden Zeilen bleibt gleich wie im oberen Beispiel. Danach wird die Zeile der Zelle "x, 1" entfernt. Da sämtliche unteren Zeilen nach oben rücken, müssen wir in dem Fall x unbedingt wieder um 1 zurücksetzen, ansonsten werden einzelne Zeilen ungewollt übersprungen. Je nach dem, wie Deine Daten angeordnet sind, kannst Du mit "x - 1" oder "x + y" y-beliebig viele Zeilen überspringen, bevor Dein Loop wieder zur Anwendung kommt. Deine Variable in der For-Schleife bezieht sich dann nicht auf die Zeile selbst, sondern auf den Fall Nummer x. Dein Loop verarbeitet somit x-beliebige Fälle - und den Code dazu brauchst Du nur ein einziges Mal zu erfassen.

Natürlich könnten sämtliche dieser Befehle leicht in Excel mittels Formel "WENN", dem Setzen eines Filters und dem Löschen der jeweiligen Zeilen vorgenommen werden. Falls es sich aber um eine grosse Tabelle handelt, oder ein wiederkehrender Prozess vorliegt, kann das Makro abgespeichert und jederzeit aufgerufen werden - es lediglich ein initialer Aufwand zur Programmierung notwendig, danach entstehen erhebliche Zeitgewinne und das Fehlerpotenzial wird minimiert (sofern alles korrekt programmiert wurde).