Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.
Wenn Sie die Daten aus Textdateien oder ähnlichen Datenquellen einlesen möchten, benötigen Sie ein Trennzeichen, welches die einzelnen Spalten einer Zeile trennt. Das ist meist durch ein Tabulator-Zeichen, das Semikolon oder das Komma gegeben. Beim Tabulator-Zeichen treten meist keine Probleme auf, aber beim Semikolon oder beim Komma kann es zu folgendem Problem kommen: Die Zeile könnte Spalten enthalten, die ihrerseits das als Trennzeichen verwendete Zeichen enthalten. In diesem Beitrag schauen wir uns an, wie Sie mit solchen Datenquellen unter VBA umgehen können.
Ein ganz einfaches Beispiel für eine solche Zeile ist diese:
1; 'Beispielartikel'; 'Dies ist ein Beispielartikel.'
Hier können wir einfach nach dem Semikolon trennen und erhalten den Inhalt der drei Spalten. Aber was ist mit der folgenden Zeile
2; 'Noch ein Beispielartikel'; 'Semikola kommen selten vor; manchmal aber schon.'
Hier können wir nun nicht mehr einfach nach dem Semikolon trennen. Stattdessen müssten wir untersuchen, ob sich das Semikolon innerhalb eines Paars von einfachen Anführungszeichen befindet – oder auch innerhalb eines Paares von normalen Anführungszeichen.
Wir starten einmal mit einer Prozedur, die nach Schema F vorgeht und so tut, als würde es innerhalb von Spalten keine Delimiter-Zeichen geben. Diese stellt in einem String-Array namens strTestdaten die beiden oben genannten Zeilen zusammen und durchläuft dieses dann in einer For…Next-Schleife über alle Elemente. Darin ruft sie die Prozedur SpaltenErmitteln auf, der sie die jeweilige Zeile übergibt sowie das zu verwendende Delimiter-Zeichen (siehe Listing 1).
Public Function Testdaten() Dim strTestdaten(2) As String Dim i As Integer Dim j As Integer Dim strSpalten() As String strTestdaten(0) = "1; 'Beispielartikel'; 'Dies ist ein Beispielartikel.'" strTestdaten(1) = "2; 'Noch ein Beispielartikel'; 'Semikola kommen selten vor; manchmal aber schon.'" For i = LBound(strTestdaten) To UBound(strTestdaten) strSpalten = SpaltenErmitteln(strTestdaten(i), ";") For j = LBound(strSpalten) To UBound(strSpalten) Debug.Print j, strSpalten(j) Next j Next i End Function
Listing 1: Prozedur, die Zeilen an eine Funktion zum Trennen einer Zeile nach dem Trennzeichen übergibt
Diese Funktion soll ein Array der Spalten der Zeile zurückliefern, die wir dann innerhalb einer weiteren For…Next-Schleife, diesmal mit der Zählervariablen j versehen, im Direktbereich des VBA-Editors ausgeben.
Die Funktion SpaltenErmitteln erwartet die zu untersuchende Zeile sowie das Delimiter-Zeichen. Sie trennt dann die Zeile mit der Split-Methode auf, welche die Zeile und den Delimiter erwartet, und ein Array der Elemente zurückliefert (siehe Listing 2).
Public Function SpaltenErmitteln(strZeile As String, strDelimiter As String) As Variant Dim strSpalten() As String strSpalten = Split(strZeile, strDelimiter) SpaltenErmitteln = strSpalten End Function
Listing 2: Funktion zum Auftrennen von Zeilen am Delimiter
Das Ergebnis für die obigen beiden Zeilen sieht dann wie folgt aus, wenn wir zusätzlich noch die Spaltennummern ausgeben:
0 1 1 'Beispielartikel' 2 'Dies ist ein Beispielartikel.' 0 2 1 'Noch ein Beispielartikel' 2 'Semikola kommen selten vor 3 manchmal aber schon.'
Sie sehen hier bereits, dass einmal drei und einmal vier Spalten ermittelt wurden. Das Semikolon innerhalb der Anführungszeichen wurde nämlich als Delimiter erkannt. Das ist keine Basis, um die Daten etwa in eine Tabelle einzutragen.
Also müssen wir einen Weg finden, um nur die Delimiter zu berücksichtigen, die sich nicht innerhalb von Anführungszeichen befinden.
Spalten nur außerhalb von Literalen erkennen
Dazu erweitern wir die Funktion SpaltenErmitteln erheblich und gehen innerhalb der Funktion prinzipiell wie folgt vor:
- Wir teilen die Zeile zunächst wieder mit der Split-Funktion an allen Stellen, die das Semikolon (oder ein anderes Trennzeichen) enthalten, auf.
- Dann durchlaufen wir alle Elemente des Arrays und schauen, ob die jeweils aktuelle Zeile eine ungerade Anzahl von Anführungszeichen enthält. In diesem Fall setzen wir einen Marker, der beim nächsten Durchlauf dafür sorgt, dass die folgende Spalte an die zuvor untersuchte angehängt wird. Das wiederholen wir solange, bis wir nochmal in einer Spalte eine ungerade Anzahl von Anführungszeichen vorfinden. Dann schließen wir die Zeile ab und ändern den Wert dieses Markers.
Im Detail sieht das wie in Listing 3 aus. Die Funktion SpaltenErmitteln nimmt nun noch einen weiteren Parameter entgegen, mit dem Sie festlegen, welches Zeichen als Anführungszeichen verwendet wird – zum Beispiel das Hochkomma oder das normale Anführungszeichen.
Public Function SpaltenErmitteln(strZeile As String, strDelimiter As String, strAnfuehrungszeichen As String) As Variant Dim strSpalten() As String Dim strSpaltenBereinigt() As String Dim i As Integer Dim intAnzahlSpalten As Integer Dim intAnzahlAnfuehrungszeichen As Integer Dim bolAnfuehrungszeichen As Boolean Dim strTemp As String strSpalten = Split(strZeile, strDelimiter) For i = LBound(strSpalten) To UBound(strSpalten) intAnzahlAnfuehrungszeichen = Len(strSpalten(i)) - Len(Replace(strSpalten(i), strAnfuehrungszeichen, "")) If intAnzahlAnfuehrungszeichen Mod 2 = 1 Then If bolAnfuehrungszeichen = False Then strTemp = strSpalten(i) bolAnfuehrungszeichen = True Else strTemp = strTemp & strDelimiter & strSpalten(i) ReDim Preserve strSpaltenBereinigt(intAnzahlSpalten) strSpaltenBereinigt(intAnzahlSpalten) = strTemp intAnzahlSpalten = intAnzahlSpalten + 1 bolAnfuehrungszeichen = False End If Else If bolAnfuehrungszeichen = False Then ReDim Preserve strSpaltenBereinigt(intAnzahlSpalten) strSpaltenBereinigt(intAnzahlSpalten) = strSpalten(i) intAnzahlSpalten = intAnzahlSpalten + 1 Else strTemp = strTemp & strDelimiter & strSpalten(i) ReDim Preserve strSpaltenBereinigt(intAnzahlSpalten) strSpaltenBereinigt(intAnzahlSpalten) = strTemp intAnzahlSpalten = intAnzahlSpalten + 1 End If End If Next i SpaltenErmitteln = strSpaltenBereinigt End Function
Listing 3: Funktion zum Auftrennen von Zeilen am Delimiter mit Berücksichtigung enthaltener Anführungszeichen
Dann deklarieren wir zwei Arrays. Das Erste nimmt das Ergebnis der ersten Split-Anweisung entgegen, das einfach nur eine Unterteilung der Zeile an allen Vorkommen des Delimiters vornimmt.
Das Zweite soll dann die tatsächlichen Spalten aufnehmen:
Dim strSpalten() As String Dim strSpaltenBereinigt() As String
i ist die Laufvariable zum Durchlaufen der Elemente des Arrays strSpalten, intAnzahlSpalten ist die Anzahl der Spalten zum Redimsionieren des im zweiten Schritt zusammengestellten Arrays, intAnzahlAnfuehrungszeichen nimmt die Anzahl der Anführungszeichen innerhalb eines Element des ersten Arrays auf und bolAnfuehrungszeichen gibt an, ob sich die Schleife gerade mit einem Element beschäftigt, das entweder ein öffnendes Anführungszeichen enthält oder auf ein solches Element folgt.
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
Testzugang
eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel
diesen und alle anderen Artikel mit dem Jahresabo