Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

Textdatei in Access-Projekt einlesen

Begonnen von ellinho, März 01, 2012, 08:54:55

⏪ vorheriges - nächstes ⏩

Bitsqueezer

Hallo Karsten,

klar, in Access ist auch zu ADO entsprechende Hilfe vorhanden. Die Online-Hilfe erweitert sich mit Einbinden der entsprechenden Verweise. Darüber hinaus findest Du unter dem Begriff "ADO" (aber nicht "ADO.NET", das ist etwas völlig anderes) tonnenweise Informationen im Internet.

Das mit TransferText dürfte deshalb nicht funktionieren, da es in ADPs keine lokalen Tabellen gibt, also auch keine Access-Systemtabellen, in denen diese Spezifikationen gespeichert sind. Du kannst versuchen, die Spezifikation mit dem Assistenten neu zu erstellen und testen, ob Du es speichern kannst und damit wieder aufrufen (dürfte dann irgendwo auf dem SQL Server gespeichert werden), weiß aber nicht, ob das funktioniert, da ich die "TransferXXX"-Befehle grundsätzlich nicht verwende wegen zuvieler Probleme und Beschränkungen. In SQL Server stehen Dir auch die SQL Server Integration Services zur Verfügung, mit denen man solche Importe mit gleichzeitiger Datenumwandlung erledigen kann, habe ich selbst aber auch noch nicht probiert, kann Dir dazu also keine Details sagen.

Gruß

Christian
  •  

ellinho

Dankeschön erst mal. Ich mache mich mal schlau.
  •  

ellinho

Hallo.
Ich habe gelesen und gelesen...und leider nichts gefunden, was mich weiterbringen würde. Der Fehler

Fehler : Die Textdateispezifikation 'Datenimport_TXTImport' ist nicht vorhanden.
Importieren, Exportieren oder Verknüpfen ist mit dieser Spezifikation nicht möglich.


ist also noch aktuell. Eine Textdateispezifikation kann ich mir in einem adp-Projekt ja leider nicht speichern, da die Schaltfläche inaktiv ist. Hat niemand eine Idee, wie der Code an folgender Stelle zu ändern ist ???

DoCmd.TransferText TransferType:=acImportDelim, SpecificationName:=Import_Spez_TXT$, _
        TableName:=Zwischentabelle$, FileName:=DateiQ$, HasFieldNames:=True


Ich werde aus sämtlichen Hilfethemen nicht schlau.

Gruß
Karsten
  •  

Bitsqueezer

Hallo,

also nach einem kurzen Blick in die Hilfe ergibt sich eindeutig, daß in ADPs das Angeben von Spezifikationen nicht möglich ist, aus dem oben bereits genannten Grund: Weil es keine lokalen Tabellen gibt. Spezifikationen werden in einer herkömmlichen Access Datenbank in den Systemtabellen MSysIMEXColumns und MSysIMEXSpecs gespeichert und können auch nur von da geladen werden, also kannst Du TransferText wohl vergessen.

Aber es gibt eine andere Möglichkeit, nämlich ADO: Damit kann man eine Spezifikation als "Schema.ini" speichern, die im gleichen Ordner wie die Datenbankdatei liegen muß, dann kann man diese zum Importieren mit ADO verwenden, das Schreiben auf den Server muß man dann allerdings in einer Recordset-Schleife mit vielen INSERTs erledigen.

Näheres mit genauer Anleitung hier:

http://msdn.microsoft.com/en-us/library/ms974559.aspx

Eine andere Variante ist die Benutzung eines BULK INSERTs, eine Beschreibung gibt es zum Beispiel hier:

http://sqlserver2000.databases.aspfaq.com/how-do-i-load-text-or-csv-file-data-into-sql-server.html
http://blog.sqlauthority.com/2008/02/06/sql-server-import-csv-file-into-sql-server-using-bulk-insert-load-comma-delimited-file-into-sql-server/

Und die komfortable Methode, mit der man am meisten machen kann, ist die Benutzung der SQL Server Integration Services, hier eine Anleitung, wie man eine CSV-Datei damit importieren kann:

http://blog.sqlauthority.com/2011/05/12/sql-server-import-csv-file-into-database-table-using-ssis/

Wer will angesichts solch komfortabler Möglichkeiten noch mit dem schrottigen TransferText arbeiten...?

Gruß

Christian

  •  

ellinho

#19
Hallo Christian.

Danke zunächst einmal für die weitreichenden Hinweise. Ich habe mich damit beschäftigt und mich für die Variante des BULK INSERTS entschieden. Habe nun eine halbwegs funktionierende Variante. Halbwegs deswegen, da es noch drei Dinge gibt, die geändert werden müssten. Die Textdatei, die importiert wird, ist folgendermaßen aufgebaut: Personalnummer;Monat;Jahr;Stunden;
Beispiel :
000001;2;2012;99,50;
000002;2;2012;104,50;
usw.
In der SQL-Sicht wird mir die Personalnummer in der zweiten Zeile mit einem Leerzeichen davor eingerückt angezeigt, in der Ansicht über die Tabelle in der adp bleibt das Feld Personalnummer in der betreffenden Zeile leer. Es liegt nicht an den führenden Nullen. Habe das mit 100002 statt 000002 getestet. Da stimmt etwas am ROWTERMINATOR nicht.
ROWTERMINATOR = ';'
Aha. Gerade ausprobiert : Sobald ich das Semikolon hinter dem letzten Datensatz in der Zeile entferne und den ROWTERMINATOR = "/N" setze, funktioniert es. Habe ich die Semikolon am Ende jeder Zeile drin stehen und den ROWTERMINATOR =";/N", dann sind alle Zeilen bis auf die letzte in Ordnung. In der letzten Zeile hinter dem letzten Wert steht dann ein Semikolon. Die Daten werden leider so von dem anderen Programm übergeben. Gibt es eine Möglichkeit, den ROWTERMINATOR so einzustellen, dass man mit den vorhandenen Datenformaten arbeiten kann ?


Die beiden anderen Sachen hängen irgendwie zusammen. Die Textdatei wird einmal monatlich von einem anderen Programm übergeben und in das Importverzeichnis gestellt. Allerdings trägt diese immer einen anderen Namen (aktueller Zeitstempel.txt). Da ich die Textdatei nach dem Import löschen möchte (dazu fehlt mir noch der Befehl bzw. Aufbau und Einbindung in meine Funktion, DELETE oder KILL 'C:\TEST\test.txt' funktioniert leider nicht), wäre es ja ungefährlich, wenn man jede x-beliebige Textdatei, die sich im Importverzeichnis steht, mit der BULK INSERT-Variante importieren könnte. Ist das möglich...so in der Form ....... FROM 'C:\TEST\*.txt' ?????

Hier die momentane Funktion :

BULK INSERT PersonalSQL.dbo.geleisteteStd
   FROM 'C:\TEST\test.txt'
   WITH
   (
       FIRSTROW = 1,
       FIELDTERMINATOR = ';',
       ROWTERMINATOR = ';'
    )


Gruß
Karsten
  •  

Bitsqueezer

Hallo Karsten,

BULK INSERT ist eben "nur" ein SQL Befehl und hat nicht so weitreichende Einstellungsmöglichkeiten, darum sagte ich ja schon, die beste Methode sind die SSIS, weil man da eben alles genau einstellen kann.

Wenn das aber das einzige Problem ist, dann hänge doch einfach einen UPDATE-Befehl dahinter, der einfach dem letzten Wert das Semikolon wieder entfernt.

Einen Joker kannst Du sicher nicht verwenden, aber ein Workaround wäre, die gewünschte Textdatei einfach umzubenennen, den BULK INSERT laufenzulassen und danach die Datei zu löschen. Ansonsten könntest Du den Befehl aber auch einfach als dynamisches SQL in VBA zusammensetzen und dann kannst Du ja nach Belieben den Dateinamen im String austauschen.

Habe selbst noch nicht mit BULK INSERT gearbeitet, kann Dir da also keine besondere Hilfestellung geben.

Gruß

Christian
  •  

ellinho

Hallo Christian.

Zitatein Workaround wäre, die gewünschte Textdatei einfach umzubenennen, den BULK INSERT laufenzulassen und danach die Datei zu löschen
Das ist leider nicht so gewünscht, da dann alles händisch erfolgen muss und nicht automatisiert abläuft.
ZitatAnsonsten könntest Du den Befehl aber auch einfach als dynamisches SQL in VBA zusammensetzen und dann kannst Du ja nach Belieben den Dateinamen im String austauschen.
Wenn ich das mal schaffen würde.  ??? Da muss ich passen. Allein die Einbindung des BULK INSERT in das adp-Projekt über Schaltfläche bringt mich ja schon ins Schwitzen, da der BULK INSERT als SQLQuery.sql abgespeichert wird und in meinem adp-Projekt nicht auftaucht.

Danke trotzdem für Deine Erklärungen

Gruß
Karsten
  •  

Bitsqueezer

Hallo Karsten,

das ist ja nur das Speichern einer (beliebigen) Query innerhalb von SQL Server Management Studio. Kannst Du natürlich speichern, aber das ist nur zu Deinem Privatvergnügen und hat mit einem Frontend ja nichts zu tun.

Einen SQL-Befehl per String zusammenzusetzen in VBA sollte ja nicht das Problem sein, oder? Etwas wie strSQL="BULK INSERT....".

Und natürlich war mit umbenennen und löschen keine manuelle Tätigkeit gemeint, sondern per Code, schließlich gibt es für Dateibearbeitung ja genug VBA-Befehle (Kill etwa usw.).

Gruß

Christian
  •  

ellinho

Hallo Christian.

ZitatUnd natürlich war mit umbenennen und löschen keine manuelle Tätigkeit gemeint, sondern per Code, schließlich gibt es für Dateibearbeitung ja genug VBA-Befehle (Kill etwa usw.).
Sorry. Das hatte ich falsch verstanden. Ich versuche es mal mit VBA. Danke Dir erstmal.

Gruß
Karsten
  •  

ellinho

Wenn ich das so mache :

Public Function Textdatei_importieren()
Dim strSQL As String
strSQL = "BULK INSERT PersonalSQL.dbo.geleisteteStd FROM 'C:\TEST\test.txt' WITH(FIRSTROW = 1,FIELDTERMINATOR = ';',ROWTERMINATOR = '\;\n')"
End Function

passiert aber nichts.  ???
  •  

Bitsqueezer

Hallo Karsten,

jetzt willst Du mich aber veräppeln, oder? Du bist doch immer noch der gleiche, der das TransferText-Skript zu Beginn dieses Threads geschrieben hat. Da stehen sowohl VBA-Befehle zur Dateimanipulation wie auch dynamisches SQL aus einem String, die Du ausführst. Und jetzt überleg nochmal.

Gruß

Christian
  •  

ellinho

Nee. Das wollte ich nicht. War nur irgendwann sehr verwirrt.
Habe es nun soweit hinbekommen. Allerdings "stolpert" SQL da noch über Kommata bei Dezimalzahlenwerten und möchte gerne einen Punkt haben. Habe etwas über die REPLACE Funktion gelesen. Ist das wohl auch bei zu importierenden Textdateien möglich oder nur für Tabellen?

Gruß
Karsten
  •  

Bitsqueezer

Hallo Karsten,

da ein String bis zu 2GB groß sein kann, kannst Du eine Textdatei, die nicht größer ist, z.B. mit dem FileStream-Objekt einlesen, Replace anwenden und wieder speichern. Sofern nicht Kommata irgendwo anders als in Zahlenwerten stehen....

Für weitere Infos zu BULK INSERT mußt Du schon selbst googlen, ich sage ja, ich arbeite nicht damit.

Gruß

Christian
  •  

ellinho

Hallo.
Habe mein Problem gelöst. Habe eine Temp_Import Tabelle mit dem Datentyp nvarchar für die Spalte "Stunden" angelegt, die mit dem BULK INSERT gefüllt wird. Als nächstes läuft ein Replace, bei dem alle Kommata in der Tabelle Temp_Import durch Punkte ersetzt werden. Danach werden die Inhalte von Temp_Import in die Arbeitstabelle geleisteteStd kopiert, in der das Feld "Stunden" vom Datentyp decimal ist, da mit diesen Werten weitergerechnet wird. Zu guter Letzt werden dann die Inhalte aus der Temp_Import Tabelle wieder gelöscht. Habe im Access-Projekt alles über ein Makro eingebunden, das über eine Schaltfläche angestoßen wird.
Danke für jegliche Hilfestellungen.

Gruß
Karsten
  •