Feldinhalte aufteilen, Teil I

Wenn sie Daten etwa aus Excel-Tabellen oder anderen Quellen importieren, liegen diese nicht immer in der gewünschten Form vor. Dann sind Felder wie Vorname und Nachname in einem Feld zusammengefasst, oder Sie möchten vielleicht Straße und Hausnummer trennen und auf zwei Felder aufteilen. Wie das mit möglichst wenig manuellem Aufwand gelingt, zeigen wir in diesem Artikel am Beispiel von Straße und Hausnummer.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1905_FeldinhalteAufteilen.accdb.

Wo und wie aufteilen

Bevor wir uns überhaupt an eine Tabelle heranwagen, die Daten zum Aufteilen enthält, machen wir uns mit dem Handwerkzeug vertraut, das wir dazu benötigen – und das heißt in diesem Fall Zeichenkettenfunktionen. Schauen wir uns zunächst ein einfaches Beispiel an – eine Straße mit einer Hausnummer, wobei beide Informationen durch ein Leerzeichen getrennt sind:

Gerichtsstr. 27

Das ist ein einfacher Fall: Wir brauchen nur das Leerzeichen in der Zeichenkette zu suchen und den Teil davor als Straße und den dahinter als Hausnummer zu speichern.

Das erledigen wir mit folgendem Codeschnippsel (siehe Prozedur StrasseUndHausnummer_1). Wir deklarieren eine Variable für den Ausgangsausdruck sowie für die resultierenden Elemente:

Dim strStrasseUndHausnummer As String
Dim strStrasse As String
Dim strHausnummer As String

Dann legen wir den Startausdruck fest:

strStrasseUndHausnummer = "Gerichtsstr. 27"

Die Strasse ermitteln wir, indem wir das erste Auftreten eines Leerzeichens suchen und den Teil bis zu diese Leerzeichen extrahieren:

strStrasse = Left(strStrasseUndHausnummer,              InStr(1, strStrasseUndHausnummer, " ") - 1)

Bei der Hausnummer sieht es ähnlich aus, nur dass wir mit der Mid-Funktion hier den Teil nach dem Leerzeichen ermitteln:

strHausnummer = Mid(strStrasseUndHausnummer, InStr(1,                       strStrasseUndHausnummer, " ") + 1)

Danach geben wir beides aus:

Debug.Print "*" & strStrasse & "*"
Debug.Print "*" & strHausnummer & "*"

Die Sternchen geben wir hier aus, um sicherzustellen, dass das Leerzeichen nicht in einer der beiden Zeichenketten enthalten ist. Wir erhalten:

*Gerichtsstr.*
*27*

Das war der erste, naive Ansatz. Dieser funktioniert schon nicht mehr, wenn wir diese Straße untersuchen:

Borkhofer Str. 17

Hier erhalten wir dann:

*Borkhofer*
*Str. 17*

Hier haben wir schon ein Leerzeichen im Straßennamen. Wir müssen also nicht das erste, sondern das letzte Leerzeichen ermitteln. Dem werden wir in der nächsten Version gerecht (siehe Prozedur StrasseUndHausnummer_2). Hier speichern wir die Position des letzten Leerzeichens auch direkt in einer Variablen:

Dim intLetztesLeerzeichen As Integer
strStrasseUndHausnummer = "Borkhofer Str. 17"
intLetztesLeerzeichen = InStrRev(                           strStrasseUndHausnummer, " ")

Damit ermitteln wir dann wie zuvor die beiden Teile des Strings:

strStrasse = Left(strStrasseUndHausnummer,                               intLetztesLeerzeichen - 1)
strHausnummer = Mid(strStrasseUndHausnummer, _
                             intLetztesLeerzeichen + 1)

Das Ergebnis sieht nun wie gewünscht aus:

*Borkhofer Str.*
*17*

Testroutine schreiben

Aber klappt das auch noch für unser zuerst verwendetes Beispiel Das können wir ja leicht und zuverlässig testen, indem wir aus unserer bisherigen Prozedur eine Funktion machen, diese mit verschiedenen Parameterwerten aufrufen und die Ergebnisse mit den erwarteten Ergebnissen abgleichen.

Wie das geht, haben wir im Detail im Artikel VBA-Funktionen testen beschrieben. Dort haben wir die Funktion StrasseUndHausnummer auch etwas umgestaltet, sodass diese nun drei Parameter enthält: den Eingangsparameter strStrasseUndHausnummer und die Ausgangsparameter strStrasse und strHausnummer. Wie unterscheiden sich Eingangs- und Ausgangsparameter Auf den ersten Blick gibt es keinen sichtbaren Unterschied, was aber daran liegt, dass das Schlüsselwort ByRef, welches für die Verwendung von Ausgangsparametern zwingend erforderlich ist, standardmäßig verwendet wird. Die Funktion sieht nun im aktuellen Zustand wie in Listing 1 aus.

<font color=blue>Public Function </font>StrasseUndHausnummer(strStrasseUndHausnummer<font color=blue> As String</font>, strStrasse<font color=blue> As String</font>, strHausnummer<font color=blue> As String</font>)<font color=blue> As Boolean</font>
     <font color=blue>Dim </font>intLetztesLeerzeichen<font color=blue> As Integer</font>
     intLetztesLeerzeichen = <font color=blue>InStrRev</font>(strStrasseUndHausnummer, " ")
     strStrasse = <font color=blue>Left</font>(strStrasseUndHausnummer, intLetztesLeerzeichen - 1)
     strHausnummer = <font color=blue>Mid</font>(strStrasseUndHausnummer, intLetztesLeerzeichen + 1)
     StrasseUndHausnummer = <font color=blue>True</font>
End Function

Listing 1: Funktion zum Ermitteln von Strasse und Hausnummer aus einer Zeichenkette

Hausnummer mit Leerzeichen

Wir sind nun soweit, dass wir Leerzeichen im Straßennamen nicht mit dem Leerzeichen zwischen Straße und Hausnummer verwechseln. Der nächste Schritt ist, dass wir Hausnummern erkennen, die selbst ein Leerzeichen enthalten. Das sollte normalerweise nicht der Fall sein, aber es kann sein, dass der Benutzer etwa folgende Zeichenkette eingibt:

Gerichtsst. 2 a

Mit der aktuellen Version unserer Funktion StrasseUndHausnummer erhalten wir für die Strasse nun den Wert Gerichtsstr. 2 und als Hausnummer a. Wie können wir das noch korrekt behandeln Wir könnten prüfen, ob die Zeichen vor dem letzten Leerzeichen numerisch sind und diese dann noch in die Hausnummer übernehmen. Wie würden wir das machen Dieser Schritt würde nach den bisherigen Schritten stattfinden und wir würden den Inhalt von strStrasse separat untersuchen.

Möchten Sie weiterlesen? Dann lösen Sie Ihr Ticket!
Hier geht es zur Bestellung des Jahresabonnements des Magazins Access [basics]:
Zur Bestellung ...
Danach greifen Sie sofort auf alle rund 400 Artikel unseres Angebots zu - auch auf diesen hier!
Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:

Schreibe einen Kommentar