Lektionen/Werkzeugkasten

Reguläre Ausdrücke in VBA

Profi11 Min. Lesezeit

Manche Textaufgaben lassen sich mit InStr, Mid und Replace nur mühsam lösen: Ist das eine gültige E-Mail-Adresse? Wie hole ich alle Zahlen aus einem Freitext? Wie entferne ich alle doppelten Leerzeichen auf einen Schlag? Hier kommen reguläre Ausdrücke ins Spiel – kompakte Muster, die beschreiben, wie ein Text aussehen soll. VBA hat sie nicht eingebaut, aber über eine Windows-Bibliothek sind sie in Access sofort nutzbar.

Die RegExp-Bibliothek einbinden

Reguläre Ausdrücke stecken in der Bibliothek „Microsoft VBScript Regular Expressions 5.5". Du hast zwei Wege, sie zu benutzen.

Early Binding (mit Verweis): Im VBA-Editor unter Extras → Verweise den Haken bei Microsoft VBScript Regular Expressions 5.5 setzen. Danach hast du IntelliSense und kannst typisiert deklarieren:

Dim re As New RegExp

Late Binding (ohne Verweis): Du erzeugst das Objekt zur Laufzeit. Das ist portabler – die Datenbank läuft ohne manuell gesetzten Verweis auf jedem Rechner:

Dim re As Object
Set re = CreateObject("VBScript.RegExp")

Tipp: Für Datenbanken, die du weitergibst, ist Late Binding die sicherere Wahl. Fehlt der Verweis auf dem Zielrechner, kompiliert Early-Binding-Code gar nicht erst. Die Beispiele hier nutzen darum CreateObject.

Die drei Eigenschaften

Ein RegExp-Objekt steuerst du über drei Eigenschaften:

EigenschaftBedeutung
Patterndas Suchmuster (der reguläre Ausdruck)
GlobalTrue = alle Treffer, False = nur der erste
IgnoreCaseTrue = Groß-/Kleinschreibung egal
Dim re As Object
Set re = CreateObject("VBScript.RegExp")
re.Pattern = "\d+"       ' eine oder mehr Ziffern
re.Global = True
re.IgnoreCase = True

Test: passt das Muster?

Test liefert True oder False, je nachdem, ob das Muster im Text vorkommt. Ideal für Validierungen:

Public Function IstEmail(ByVal wert As String) As Boolean
    Dim re As Object
    Set re = CreateObject("VBScript.RegExp")
    re.Pattern = "^[\w.\-]+@[\w\-]+\.[A-Za-z]{2,}$"
    re.IgnoreCase = True
    IstEmail = re.Test(wert)
End Function
Debug.Print IstEmail("anna@example.com")   ' True
Debug.Print IstEmail("kein-at-zeichen")    ' False
Debug.Print IstEmail("a@b.c")              ' False – TLD zu kurz

Die wichtigsten Musterzeichen im Schnellüberblick:

ZeichenBedeutung
\deine Ziffer, \D alles außer Ziffer
\wBuchstabe, Ziffer oder _
\sLeerraum (Space, Tab), \S das Gegenteil
.ein beliebiges Zeichen
+ * ?ein-/mehrmals, null-/mehrmals, optional
^ $Anfang bzw. Ende des Textes
[A-Za-z]Zeichenklasse: ein Zeichen aus dem Bereich
{2,4}zwischen 2 und 4 Wiederholungen

Execute und Matches: Treffer herausholen

Execute liefert eine MatchCollection – alle Fundstellen. Jeder Match kennt den gefundenen Text (.Value), die Position (.FirstIndex, 0-basiert) und die Länge (.Length):

Public Sub ZahlenExtrahieren()
    Dim re As Object, treffer As Object, m As Object
    Set re = CreateObject("VBScript.RegExp")
    re.Pattern = "\d+"
    re.Global = True

    Set treffer = re.Execute("Rechnung 4711 über 250 Euro, Pos 3")
    Debug.Print treffer.Count       ' 3

    For Each m In treffer
        Debug.Print m.Value & " an Position " & m.FirstIndex
    Next m
    ' 4711 an Position 9
    ' 250 an Position 18
    ' 3 an Position 32
End Sub

Setzt du Global = False, enthält die Collection nur den ersten Treffer.

Gruppen mit SubMatches

Klammern (...) im Muster bilden Gruppen. Ihre Inhalte liest du je Treffer über SubMatches aus – praktisch, um Teile gezielt herauszuziehen:

Dim re As Object, treffer As Object, m As Object
Set re = CreateObject("VBScript.RegExp")
re.Pattern = "(\d{2})\.(\d{2})\.(\d{4})"   ' TT.MM.JJJJ
re.Global = True

Set treffer = re.Execute("Fällig am 15.08.2026, geliefert 03.09.2026")
For Each m In treffer
    Debug.Print "Jahr: " & m.SubMatches(2) & ", Monat: " & m.SubMatches(1)
Next m
' Jahr: 2026, Monat: 08
' Jahr: 2026, Monat: 09

SubMatches ist 0-basiert und enthält nur die Klammergruppen, nicht den Gesamttreffer.

Replace: ersetzen per Muster

Replace tauscht alle Treffer aus – deutlich mächtiger als das eingebaute Replace, weil die zu ersetzende Stelle ein Muster sein darf. Klassiker: mehrfache Leerzeichen zu einem einzigen zusammenziehen und Text bereinigen:

Public Function LeerraumNormalisieren(ByVal text As String) As String
    Dim re As Object
    Set re = CreateObject("VBScript.RegExp")
    re.Pattern = "\s+"       ' ein oder mehr Leerraumzeichen
    re.Global = True
    LeerraumNormalisieren = Trim(re.Replace(text, " "))
End Function
Debug.Print LeerraumNormalisieren("  Hallo    Welt   hier ")  ' "Hallo Welt hier"

Im Ersetzungstext greifst du mit $1, $2 … auf Klammergruppen zu. So drehst du zum Beispiel ein Datumsformat um:

Dim re As Object
Set re = CreateObject("VBScript.RegExp")
re.Pattern = "(\d{2})\.(\d{2})\.(\d{4})"
re.Global = True
Debug.Print re.Replace("Termin 15.08.2026", "$3-$2-$1")
' "Termin 2026-08-15"

Praxis: Telefonnummern säubern

Ein häufiger Fall beim Import: Nummern enthalten Leerzeichen, Schrägstriche und Klammern. Ein Muster entfernt alles außer Ziffern und einem führenden +:

Public Function TelefonBereinigen(ByVal roh As String) As String
    Dim re As Object
    Set re = CreateObject("VBScript.RegExp")
    re.Pattern = "[^\d+]"    ' alles, was keine Ziffer und kein Plus ist
    re.Global = True
    TelefonBereinigen = re.Replace(roh, "")
End Function
Debug.Print TelefonBereinigen("+49 (0) 40 / 123-456")   ' "+49040123456"

Das ^ innerhalb der eckigen Klammern negiert die Zeichenklasse: „alles außer Ziffer und Plus".

Grenzen und Stolpersteine

Reguläre Ausdrücke sind stark, aber kein Allheilmittel:

  • Performance: Erzeuge das RegExp-Objekt nicht in jeder Schleifeniteration neu. Baue es einmal auf und wende es wiederholt an – das spart bei großen Datenmengen spürbar Zeit.
  • VBScript-Dialekt: Diese Engine kann keine Lookbehinds und keine benannten Gruppen. Lookaheads ((?=...)) funktionieren, benannte Gruppen (?<name>...) nicht. Halte Muster darum eher einfach.
  • E-Mail & Co. sind komplex: Ein RegExp prüft nur die Form, nicht die Existenz. Ein Muster für „gültige E-Mail" nach RFC ist praktisch unlesbar – begnüge dich mit einer pragmatischen Näherung wie oben.
  • Lesbarkeit: Kommentiere jedes nicht-triviale Muster. In drei Monaten entziffert niemand ^[\w.\-]+@[\w\-]+\.[A-Za-z]{2,}$ ohne Hinweis.

Achtung: Für einfache, feste Ersetzungen bleibt das eingebaute Replace schneller und klarer. Greif erst zu RegExp, wenn die zu findende Stelle ein Muster ist und nicht ein fester Text.

Zusammengefasst

  • Reguläre Ausdrücke kommen aus „Microsoft VBScript Regular Expressions 5.5"; nutze CreateObject("VBScript.RegExp") (Late Binding) für portablen Code.
  • Steuere über Pattern, Global und IgnoreCase; Test prüft, Execute liefert alle Treffer als MatchCollection.
  • SubMatches greift auf Klammergruppen zu, im Replace-Text nutzt du $1, $2 für dieselben Gruppen.
  • Typische Aufgaben: E-Mail/Format prüfen, Zahlen extrahieren, Leerraum und Sonderzeichen bereinigen.
  • Achte auf Performance (Objekt wiederverwenden) und die Grenzen des VBScript-Dialekts – kein Lookbehind, keine benannten Gruppen.
Nächste Lektion
Domänenfunktionen: DLookup, DCount, DSum