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.

Dynamische Titel (Formel "TEXT")

Im kürzlich veröffentlichten Beitrag Dynamische Ergebnisse (Formel "Teilergebnis") wurde gezeigt, wie auf angewandte Filter reagiert werden kann, sodass stets das korrekte Ergebnis geliefert wird. Die herkömmliche SUMME-Formel berücksichtigt den aktiven Filter nicht, wohingegen sich TEILERGEBNIS nur auf die noch angezeigten Daten bezieht.

Wir verwenden hier wiederum die Verkäufe, wie in nachfolgendem Bild ersichtlich:

Teilergebnis1

Ziel ist es nun, oberhalb der Überschrift (Datum; Kundennummer; Umsatz; Absatz) einen Titel einzufügen. Dieser soll folgendermassen lauten: "Verkäufe von 10.01.2014 bis 11.02.2014". Desweiteren soll der Titel dynamisch sein, damit direkt auf den aktiven Filter reagiert und stets der korrekte Zeitraum angegeben wird.

Text und Formel verketten

In diesem Abschnitt beziehe ich mich auf bereits im Blog Inhalte aus Zellen miteinander verketten gezeigte Inhalte, wo wir sowohl Text und Formeln/Bezüge miteinander verknüpft haben. Nach dem Einfügen einer neuen Zeile geben wir vorerst in Zelle A1 folgendes ein:

="Verkäufe von "

Um nun das tiefste Datum zu ermitteln, verwenden wir die Formel "TEILERGEBNIS", mit der Funktion "MIN" (Minimum). In der Zelle A1 haben wir demzufolge:

="Verkäufe von "&TEILERGEBNIS(5;A3:A9)

Wichtig ist hier das Kaufmännische-Und-Zeichen (&), welches uns ermöglicht, sowohl Text ("Verkäufe von ") und dann eben auch Bezüge oder Formeln (eingeläutet mit dem &-Zeichen) miteinander zu kombinieren.

Nach dieser Eingabe siehst Du, dass der Titel noch nicht vollständig ist, wir erhalten als Resultat "Verkäufe von 41649". Du bist jedoch auf dem richtigen Weg - der 10. Januar 2014 ist einfach noch nicht korrekt formatiert worden! Es ist hier zu erwähnen, dass jedes Datum als Zahl im System hinterlegt ist, beginnend beim 1. Januar 1900 - probier es doch mal aus: Gib in einer beliebigen Zelle "01.01.1900" ein und formatiere diesen Wert in eine Zahl um - Du erhälst "1". Dies erlaubt es uns, mit Daten zu rechnen (beispielsweise Rechnungsdatum +30 = Fälligkeitsdatum). Aber zurück zum Thema: Wie kannst Du nun das Datum umformatieren? Hier kommt die Formel "TEXT" zum Zuge.

Die Formel "TEXT"

Mittels der Formel "TEXT" kann das Format eines Wertes beliebig angepasst werden. In unserem Falle für ein Datum bedeutet dies: Das Datum 10.01.2014 (oder die Zahl 41649) kann beliebig umformatiert werden. Die Formelsyntax von "TEXT" verlangt nach einem Wert [Bezug (Datum oder Zahl)] und nach dem gewünschten Format. Der Bezug ist in unserem Beispiel das Datum 10.01.2014. Als Textformat kannst Du nun z.B. “T. MMMM JJJ“ eingeben. Das Resultat: "10. Januar 2014". Auch die erfassten Punkte und Leerschläge wurden akzeptiert und berücksichtigt. Doch was bedeuten diese "T, M & J" im Detail?

T steht für Tag, M für Monat und J für Jahr. Ich liste hier auf, welche Formate möglich sind:

T = Tag ohne vorhergehende Null (1., 2., 10., 20. Januar)

TT = Tag mit vorhergehender Null (01., 02., 10., 20. Januar)

TTT = Tag ausgeschrieben, abgekürzt (Mo, Di, Mi, Do, Fr, Sa, So)

TTTT = Tag ausgeschrieben (Montag, Dienstag, Mittwoch, …)

 

M = Monat ohne vorhergehende Null (1., 2., 10., 12. 2014)

MM = Monat mit vorhergehender Null (01., 02., 10., 12. 2014)

MMM = Monat ausgeschrieben, abgekürzt (Jan, Feb, Mrz, …)

MMMM = Monat ausgeschrieben (Januar, Februar, März, …)

 

J oder JJ = Jahr, abgekürzt (14, 15, 16)

JJJ oder JJJJ = Jahr, nicht abgekürzt (2014, 2015, 2016)

Bezogen auf unseren dynamischen Titel ist nun also die Formel "TEILERGEBNIS(...)" mit obiger Formel zu kombinieren. Das Teilergebnis entspricht dem Wert der TEXT-Formel, für welches das Format ("TT.MM.JJJ") bestimmt wird. In Zelle A1 steht demnach:

="Verkäufe von "&TEXT(TEILERGEBNIS(5;A3:A9);"TT.MM.JJJ")

Nun haben wir - auf den Filter reagierend - stets den tiefsten Wert/das tiefste Datum ermittelt. Um "Verkäufe von ... bis ..." zu erlangen, wäre die Formel analog oben zu erweitern. Wir gehen wiederum Schritt für Schritt vor und erweitern den Titel erstmal um den Textteil " bis ". Zu beachten ist, dass die Formel mit einem &-Zeichen und der Text mit Gänsefüsschen abzugrenzen ist. In Zelle A1 steht danach:

="Verkäufe von "&TEXT(TEILERGEBNIS(5;A3:A9);"T.MM.JJJ")&" bis "

Der letzte Schritt ist nun, noch das Maximum mittels Teilergebnis zu ermitteln. Am einfachsten kopierst Du den Teil "&TEXT(TEILERGEBNIS [...] "T.MM.JJJ")" und setzt diesen ans Ende der Formel in der Zelle A1. Die Funktion für MAX in der Formel TEILERGEBNIS ist die Nummer 4, für MIN ist es die Nummer 5. Dies ist noch anzupassen, danach hast Du einen dynamischen Titel gesetzt, der auf den Filter reagiert und Dir stets den korrekten Zeitraum angibt. Die fertigte Formel in A1 lautet:

="Verkäufe von "&TEXT(TEILERGEBNIS(5;A3:A9);"TT.MM.JJJ")&" bis "&TEXT(TEILERGEBNIS(4;A3:A9);"TT.MM.JJJ")

Du könntest nun den Datumstyp beliebig anpassen und beispielsweise den Wochentag integrieren, indem das Format in "TTTT, TT. MMMM JJJ" geändert wird. Das Resultat: Freitag, 10. Januar 2014. Daraus wird ersichtlich: Du kannst mit der Formel "TEXT" jederzeit - und schnell - den Wochentag ermitteln, indem Du als Format einfach "TTTT" wählst.

Grundsätzlich siehst Du, habe ich die Formel Schritt für Schritt aufgebaut - es wird nur unnötig kompliziert, wenn man mehrere Angaben miteinander als Formel anzugeben versucht. Ich werde in einem späteren Blog zeigen, wie ich beim Erstellen von ganzen Berichten jeweils vorgehe. Nun wünsche ich Dir jedoch erstmal viel Erfolg beim Formatieren von Daten und dem Erstellen von dynamischen Titeln und Berichten. Hinterlasse mir doch bei Fragen und Anregungen ungeniert einen Kommentar.