Datenimport aus Textdatei

By , 3. November 2010

Analog zum Artikel Regelmäßiger Datenimport realisieren wo es um den Import von Daten aus Excel ging, zeige ich in diesem Artikel auf wie man aus einer Textdatei importiert. Langweilig, kennen wir schon … mögen Sie jetzt denken. Aber lesen Sie weiter, es wird spannender als Sie denken.

Die Situation ist die gleiche wie im ersten Artikel. Sie haben ein Produktiv-Backend das 7×24 Stunden im Einsatz ist. Das bedeutet dass Sie nur bereinigte Daten in das Arbeitsbackend übertragen können. Der Lösungsweg ist der gleiche wie zuvor, der Import geschieht über eine temporäre Datenbank die zum Zwecke des Imports und der Bearbeitung der Daten per Code erstellt danach gelöscht wird.

Details zum Erstellen der temporären Datenbank und Tabelle lesen Sie bitte im ersten Artikel. Der Vereinfachung halber füge ich hier nur die Prozedur ein die Datenbank und Tabelle erstellt.

Function CreateNewDB(dbNam As String, TabName As String) As Database
    Dim wrkDefault As DAO.Workspace
    Dim dbNeu As DAO.Database

    ' Standardarbeitsbereich bestimmen.
    Set wrkDefault = DBEngine.Workspaces(0)

    'wenn Datenbank bereits vorhanden, dann löschen
    If Dir(CurrentProject.Path & "\" & dbNam & ".mdb") <> "" Then
        Kill CurrentProject.Path & "\" & dbNam & ".mdb"
    End If

    'neue Datenbank erstellen
    Set dbNew = wrkDefault.CreateDatabase(CurrentProject.Path & "\" & _
                                          dbNam & ".mdb", dbLangGeneral, dbEncrypt Or dbVersion40)

    'Tabelle erstellen
    dbNew.Execute "CREATE TABLE " & TabNam & " (" & Fields & ")"

    'Rückgabewert zuweisen
    Set CreateNewDB = dbNeu
End Function

Der nächste Schritt ist der Import aus der Textdatei. In meinem Beispiel verwendete ich eine Spaltenorientierte Textdatei mit gleich langen Spalten. Es geht aber auch mit anderen Typen wie z.B. mit einem Separator etc. Der einfachste Weg ist eine Importspezifikation zu erstellen. Wer das nicht kennt hier eine Schnellanleitung dazu:

  • Über Datei/Externe Daten/Importieren Dateityp Textfiles auswählen und die entsprechende Textdatei auswählen.
  • Ein Klick auf Importieren öffnet einen Assistenten zur Zuordnung der Spalten und der Spalteneigenschaften.
  • Man wählt einen der beiden Modis aus, also Trennzeichen oder feste Breite und klickt auf „Weiter“.
  • Danach dem Assistenten folgen. Die Eingaben sollten selbsterklärend sein.
  • Zum Schluss bevor man „Fertig stellen“ klickt die Schaltfläche „Weitere“ anklicken.
  • Ein weiteres Fenster öffnet sich wo man entsprechende Auswahlen treffen sollte.
  • Zum Schluss auf „Speichern unter“ klicken, einen Spezifikationsnamen angeben und 2x OK klicken.
  • Jetzt sind Sie wieder im ersten Fenster wo Sie den Assistenten mit „Fertig stellen“ beenden.


Um zu sehen was der Assistent erstellt hat sollten Sie unter Extras/Optionen die Systemobjekte einblenden.
Sie sehen dass Sie 2 neue Systemtabellen haben, MSysIMEXSpecs und MSysIMEXColumns.
In der ersten Tabelle sind sämtliche Einstellungen die Sie im Import-Assistenten gemacht haben gespeichert, also z.B. Datumsformat, Datums-Trennzeichen, Spezifikationsname, Spezifikaitonstyp etc.
In der zweiten Tabelle stehen die Informationen über die zu importieren Spalten, also z.b. Datentyp, Feldname, Start, Breite etc. Start und Breite beziehen sich auf die Position im Text-Dokument, nicht auf den Inhalt.
Der Zusammenhang zwischen Breite und Start wird auf folgenden Bildern verdeutlicht:

Damit der Import innerhalb der externen Datenbank funktioniert, muss dort genau die soeben angelegte Importspezifikation vorhanden sein.
Das bedeutet man muss die beiden Tabellen dort neu erstellen und die genauen Datensätze übertragen.

Das hab ich in eine Prozedur gepackt und in einem Modul ausgelagert. Um den Code brauchte ich mich dankenswerter Weise keine Gedanken machen, da ich auf vbarchiv.net was passendes gefunden habe: http://www.vbarchiv.net/tipps/tipp_876-importspezifikation-….
Vielen Dank an den Autor und das vbarchiv.net Team.

Den Code veröffentliche ich hier nicht, bitte seht bei der angegebenen Quelle nach.
Die Felder in der Tabelle MSysIMEXSpecs haben folgende Bedeutung:

DateDelim   Datumstrennzeichen
DateFourDigitYear:   0/1 = vierstellige Jahreszahl nein/ja
DateLeadingZeros:   0/1 = führende Nullstellen im Datum nein/ja
DateOrder:   Sortierung für Datum. Werte von 0 bis 5 für die versch. Reihenfolgen
DecimalPoint:   Art des Dezimalpunktes, z.B. Punkt oder Komma
FieldSeparator:   Feldertrennzeichen, z.B. Komma, Semikolon
FileType:   Typ der importierten Datei, z.B. 850 für Textfile
SpecID:   Eindeutiger ID der Spezifikation
SpecName:   Name der Importspezifikation (frei wählbar)
SpecType:   Importspezifikations-Typ, 1 = Trennzeichen, 2 = Feste Breite
StartRow:   0/1 = erste Spalte enthält Überschrift nein/ja
TextDelim:   Texttrennzeichen
TimeDelim:   Zeittrennzeichen

Das Befüllen der Tabelle MSysIMEXColumns habe ich etwas geändert um den Datentyp und den Feldnamen flexibel zu halten.

    arr1 = Array(0, 4, 10, 7, 10, 10, 7, 4, 8 ) 'Felddatentypen
    arr2 = Array(0, 12, 10, 14, 20, 20, 10, 5, 10) 'Breitenangaben
    arr3 = Array("Dummy", "Feld1", "Feld2", "Feld3", "Feld4", "Feld5", "Feld6", "Feld7", "Feld8")
    For i = 1 To 8    ' Im Beispiel für 8 Felder
        oRs.AddNew
        oRs!Attributes = 0
        oRs!DataType = arr1(i)
        oRs!FieldName = arr3(i)
        oRs!IndexType = 0
        oRs!SkipColumn = 0
        oRs!SpecID = 1
        oRs!Start = k
        oRs!Width = arr2(i)
        oRs.Update
        k = k + arr2(i)
    Next i

Die Felddatentypen muss man anhand der testweisen erstellten Importspezifikation herausfinden.
Z.B. wird die 10 für Textfelder und die 8 für Datumsfelder verwendet.

So nun der eigentliche Importvorgang:

'Temporäre DB erstellen
Set DBtemp = CreateNewDatabase("importDB", "Tabellenname")

'Temporäre DB schließen
DBtemp.Close
Set DBtemp = Nothing

'Importspezifikation in externen Datenbank anlegen
Spezifikation_Erstellen CurrentProject.Path & "\importDB.mdb"

'Objekt auf DBTemp
Set accObj = CreateObject("Access.Application")
accObj.OpenCurrentDatabase (CurrentProject.Path & "\importDB.mdb")

'Textdatei nach importDB importieren
accObj.DoCmd.TransferText acImportFixed, "importspezifikation1", "Tabellenname", "Dateiname"

Set accObj = Nothing

'Recordset auf importDB
Set DBtemp = DBEngine.Workspaces(0).OpenDatabase(CurrentProject.Path & "\importDB.mdb")

Der Trick dabei ist, dass man DoCmd.TransferText auf das erstellte Access-Objekt anwendet, und die Anweisung somit in der externen Datenbank auch ausgeführt wird.
Danach das Access-Objekt zurücksetzen und per Recordset auf die erstellte Datenbank mit den Importierten Datensätzen zugreifen und entsprechend bearbeiten.

Ist doch nun ziemlich übersichtlich geworden, obwohl doch ziemlich viel Code dahinter steckt.
Vergesst nicht die entsprechende Fehlerbehandlung auf die hier wie üblich verzichtet wird.

Bis dahin
Andreas Vogt ©2010

Leave a Reply

You must be logged in to post a comment.

OfficeFolders theme by Themocracy