Hallo zusammen,
ich versuche eine CSV Datei in meine Access Formular zu importieren.
Das habe ich über "DoCmd.TransferText acLinkDelim, ImportSpez, TmpLink, AktDatFullNam" ausgeführt.
Klapp auch prima !!!
Jetzt das Problem.
Die CSV Datei ist mehr als 255 Spalten lang, genau 457 Spalten.
Ich suche eine Möglichkeit nur einzelne Felder aus der CSV Datei in mein Formular zu übertragen.
Help me please :)
Hallo,
Du kannst doch mit dem Importassistenten genau auswählen welche
Spalten du importieren willst.
Oder werden da gar nicht erst alle Spalten der .csv angezeigt?
gruss ekkehard
Hallo Moin,
es werden genau 255 angezeigt.
Es sind aber mehr Spalten.
Habe die Spalten 1-100 ausgewählt in der Import_Spec.
Die werden dann auch übertragen.
Wenn ich aber die 101-255 auswähle werden mir die Spalten 1-100 übertragen ?
Gibt es da einen Kniff ?
siehe ImportSec !
Nun, die PDF-Datei wird kaum zu einer Lösung verhelfen. Mit einem Auszug der CSV-Daten (ggf. sensible Felder anonym gestalten) und einer kurzen Erläuterung zu den Feldern ist die Aussicht auf Hilfe vermutlich größer.
Hallo,
ZitatDas habe ich über "DoCmd.TransferText acLinkDelim, ImportSpez, TmpLink, AktDatFullNam" ausgeführt.
Klapp auch prima !!!
Heisst das denn, dass du alle Felder importieren konntest, oder eben
nur die ersten 100.
Da bleibt dir nichts anderes übrig als die .csv vorher aufzuteilen bzw.
den Export so einzurichten das da schon weniger Spalten rauskommen.
ZitatWenn ich aber die 101-255 auswähle werden mir die Spalten 1-100 übertragen ?
Dazu kann ich nichts sagen, mit so vielen Spalten arbeite(t) ich (man) in Datenbanken nicht.
Leider hast du auch den Sinn verschwiegen. Ich denke da muss zuerst
ein brauchbares Datenmodell in Access erstellt werden.
gruss ekkehard
Hallo,
das ist richtig !
Danke nochmal für die Antwort.
Also habe die CSV als XLS angehängt weil '.csv nicht anzuhängen ist ??
Die Felder sind alle als Text zu behandeln.
Wollte wegen der Größe der CSV die Felder auf mehrere Formulare aufteilen.
Klappt auch alles wunderbar aber leider nur bis zum Feld 255.
Habe den Code zum importieren angehängt.
Mit diesen Code hole ich mir die CSV in das Formular hinein.
"
Private Sub Importieren_Click()
'geteset AC97, AC2000
' es werden mehrere GLEICHARTIGE Importdateien nacheinander verknüpft und an
' eine Haupttabelle angefügt
' Voraussetzungen :
' TXT,CSV : Importspezifikation wurde erstellt und gespeichert
' Startverzeichnis für die Suche angeben
' einen Filetyp bzw Dateinamensbild freischalten
' ("*.txt";"*.csv";"2005*.xls")
' Zieltabelle, an welche die Daten angefügt werden sollen
Const ZielTab = "Zaehlerstaende"
Dim i As Integer
Dim AktDatei As String
Dim TxtDatum As String
'Datum in Text umwandeln
Debug.Print TxtDatum
Datum = Str(Date)
Debug.Print Datum
Datum = Format(Date, "yyyymmdd") ' heutiges Datum als Text z.B.: 20160622
Debug.Print Datum
DatTyp = ("Test*" & Datum & ".csv")
'Const DatTyp = "Test*.csv"
Const SuchVerzeichnis = "I:\ORG\OPOTSS\Dispatching\Zaehlerstaende_Epe\"
AktDatei = Dir(SuchVerzeichnis & "\" & DatTyp)
While Len(AktDatei) > 0
Debug.Print AktDatei
' Nächste Zeile startet Import für eine Textdatei (CSV,TXT)
EineTXTDateiEinlinkenUndAnfügen SuchVerzeichnis & "\" & AktDatei, _
ZielTab
' Nächste Zeile startet Import für eine Exceldatei (XLS)
'EineExcelDateiEinlinkenUndAnfügen SuchVerzeichnis & "\" & _
' AktDatei, ZielTab
' Nächste Zeile startet Import für eine Exceldatei (XLS) mit allen
' Tabellen
'EineExcelDateiMitAllenTabellenEinlinkenUndAnfügen SuchVerzeichnis & _
' "\" & AktDatei, _
' ZielTab
AktDatei = Dir ' nächste Datei
Wend
End Sub
Sub EineTXTDateiEinlinkenUndAnfügen(AktDatFullNam As String, _
ZielTab As String)
' eigentliche Import/Verknüfungsfunktion
Const TmpLink = "TabtmpLink" ' beliebiger Tabellenname (wird gelöscht)
Const ImportSpez = "Allgemein_Import" ' Name deiner Importspezifikation
' CSV einlinken
On Error Resume Next
DoCmd.DeleteObject acTable, TmpLink
On Error GoTo 0
'oCmd.TransferText acImportDelim, "Allgemein_Import", TableName:="Zaehler3 ", FileName:=filePath, HasFieldNames:=True
DoCmd.TransferText acLinkDelim, ImportSpez, TmpLink, AktDatFullNam
' Anfügen
CurrentDb.Execute "INSERT INTO " & ZielTab & _
" SELECT " & TmpLink & ".* " & _
"FROM " & TmpLink & ";"
End Sub
"
Hier nochmal die Test Datei als ZIP.
die *.Xls ist ja nur 255 Spalten breit :)
Zitat von: Beaker s.a. am Juni 30, 2016, 21:21:13
Hallo,
ZitatDas habe ich über "DoCmd.TransferText acLinkDelim, ImportSpez, TmpLink, AktDatFullNam" ausgeführt.
Klapp auch prima !!!
Heisst das denn, dass du alle Felder importieren konntest, oder eben
nur die ersten 100.
Da bleibt dir nichts anderes übrig als die .csv vorher aufzuteilen bzw.
den Export so einzurichten das da schon weniger Spalten rauskommen.
ZitatWenn ich aber die 101-255 auswähle werden mir die Spalten 1-100 übertragen ?
Dazu kann ich nichts sagen, mit so vielen Spalten arbeite(t) ich (man) in Datenbanken nicht.
Leider hast du auch den Sinn verschwiegen. Ich denke da muss zuerst
ein brauchbares Datenmodell in Access erstellt werden.
gruss ekkehard
Die CSV bekomme ich per Mail und ist immer gleich aufgebaut.
Ja genau dass möchte ich ja gerne erfahren !!??
Wie kann ich den Export so einrichten das man z.Bsp. nur 120 ausgesucht Felder importiert.
Immer noch Danke für die Vorschläge.
Hi,
die gezeigten Daten lassen leider ein sinnvolles Modellieren für einen Nicht-Esoteriker nicht zu.
CSV-Dateien lassen sich mit der Open (https://is.gd/PQYa90)-Anweisung öffnen. Nach dem Öffnen kann man Zeile für Zeile der Datei einlesen (Line Input # Statement (https://is.gd/K8BfiU)). Eine Zeile könnte man in ein Datenfeld (Array) aufsplitten (Split Function (https://is.gd/fumIx4)) und die gewünschten Inhalte (über entsprechende Recordset(s) oder auch Anfügeabfrage(n)) in einen oder mehrere neue Datensätze schreiben. Am Ende schließt man die Datei wieder (Close Statement (https://is.gd/RuufuD)).
Dieses Verfahren wird in Programmiersprachen allgemein als Parsen bezeichnet.
Hallo,
Ich sehe da nur zwei Möglichkeiten; - jede bessere Lösung ist willkommen.
1. Die ankommende .csv in Ecxel öffnen und auf zwei Tabelle aufteilen und
getrennt wieder als .csv abspeichern. Dann würde ich diese beiden Dateien
auch nicht in Access importieren sondern verknüpfen. Dann kannst du per
Abfrage(n) auf einzelne Felder zugreifen.
2. Import per benutzerdefiniertem Datentyp. Da weiss ich aber nicht, ob man
da nicht auch auf 255 Variablen(Felder) beschränkt ist. Bei dieser Methode
hast du auch die Möglichkeit direkt in mehrere Tabellen zu schreiben.
Prinzip (Luftcode):
Private Type ImportDS
FELD1 As String
FELD2 As String
FELD3 As String
FELD4 As String
FELD5 As String
.
.
FELD457 As String
End Type
Private Sub fImport()
Dim intDateiNr As Integer 'erste freie Dateinummer
Dim strImpDatPfad As String 'Pfad der Import-Datei
Dim intDateiNr As Integer 'erste freie Dateinummer
Dim impRec As ImportDS 'Datensatz wie oben beschrieben
Dim rst As DAO.Recordset
' strImpDatPfad = musst du irgendwo herholen
intDateiNr = FreeFile
Open strImpDatPfad For Binary As #intDateiNr Len = Len(impRec)
Get #intDateiNr, , impRec
'RS öffnen
Set rst = CurrentDb.OpenRecordset(Name:="EineTabelle")
Do Until #intDateiNr.EOF '<- bei diesem Ausdruck bin ich nicht sicher
rst.AddNew
rst.Fields("Feldname1") = impRec.FELD1
rst.Fields("Feldname2") = ImpRec.FELD2
rst.Update
Get #intDateiNr, , impRec
Loop
Close #intDateiNr
rst.Close
Set rst = Nothing
End Sub
hth
gruss ekkehard
Hallo,
zunächst Mal würde ich natürlich das "Design" der CSV-Dateien überdenken. Vllt. kannst du an der Quelle die Excel-Datei so ändern, dass sie von vornherein 2 Files erstellt...
Ansonsten:
Wenn Access die Import-Definition auf 255 Spalten beschränkt (durchaus nachvollziehbar), dann musst du eben deine eigenen Import-Definitionen definieren, etwa so:
Variante 1:
1. erstelle eine Tabelle ImpDefs mit 457 Datenfeldern (oh Graus!) als Textfelder und 457 Ja/Nein-Feldern sowie beschreibenden Textfeldern (angelegt von, Verwendung, CSV-Dateinamens-Muster...).
2. erstelle ein Formular mit 457 Textfeldern (schmal und lang für die Darstellung der Kopfzeile(n)) und 457 Checkboxen. 23 Felder nebeneinander und das 20mal untereinander. (VBA!)
3. lade per VBA die ersten Zeilen der CSV und splitte die Felder jeder Zeile. Kopiere den Split-Vektor nach jeder gelesenen Zeile in ein 2-dimensionales Array. Bau dann aus den gelesenenen Zeilen 457 aussagekräftige Textfelder zusammen, Zeilen-Umbruch jeweils mit VBCRLF, etwa so
for i= 1 to 457
for j= 1 to 5 'Bsp: erste 5 Zeilen werden eingelesen (Spaltennamen)
textfeld(i) = textfeld(i) & arrayfeld(i,j) & vbcrlf
next
next
4. schreibe diese 457 Textfelder nun in die 457 Textfelder des Formulars.
5. mit den 457 Checkboxen kannst du dann angeben, welche Felder du importieren möchtest.
6. diesen Mammut-Datensatz kannst du dann für spätere bzw. wiederkehrende Verwendung speichern.
Variante 2:
1. Tabelle ImpDefs mit ein paar beschreibenden Textfeldern.
1a. Tabelle ImpDefItems mit Referenz auf ImpDefs, einem Text- und einem Ja/Nein-Feld.
2. erstelle ein Unterformular (UFO) für ImpDefItems bestehend aus einem mehrzeiligen Textfeld und darunter einer Checkbox.
2a. erstelle ein Formuar für ImpDefs, in das du das obige Ufo platzierst und so klein wie möglich/gewünscht machst.
2b. kopiere das UFO per VBA 456mal (Link-Felder nicht vegessen)...
3. bis 6. ähnlich wie oben.
Variante 3:
1. öffne eine CSV-Datei als Muster in Excel.
2. füge eine neue 1. Zeile ein, setze in jedes Feld der Zeile ein Kontrollkästchen.
3. speichere die Datei als Muster-CSV.
Kurze Diskussion der Varianten:
v1 - grauenhaft, Mammut-Tabelle mit knapp 1000 Feldern!
v2 - besser, da normalisiert - kleine, schmale Tabellen
v1 - immenser Definitions-Aufwand (Tabellenfelder, Formularfelder)
v2 - minimaler Definitions-Aufwand, aber VBA-Code zum Kopieren der UFOs nötig
v1 - kratzt an der Access-Grenze von ca. 920 (?) Feldern pro Formular
v3 - ohne ACCESS-Klimmzüge
v3 - Namenskonvention für Muster erforderlich (als Access-Tabelle...)
v3 - geringster Aufwand
v3 - hier könnte man in einer weiteren Zeile auch noch das Ziel-Feld in der Access-Tabelle unterbringen...
Egal, welche Variante du bauen solltest - der Programm-Ablauf für den eigentlichen Daten-Import wäre dann:
1. Import-Definition laden.
2. CSV-Datei zeilenweise lesen, dabei Kopfdaten überspringen und die gewünschten Felder speichern (Zeile in Vektor splitten etc.).
Übrigens: die Variante 2 von Ekkehard halte ich für etwas zu aufwändig, da ein solcher Datentyp mit 457 einzelnen Strings im Prinzip auch nichts anderes ist als ein String-Vektor (dim MyString(457) as string).
Wenn man eine Zeile der CSV-Datei einliest, kann man sie mit SPLIT leicht in einen solchen Vektor überführen und über dessen Elemente loopen (starten bei 0).
Und noch ein Übrigens: in der Beispiel-xls sind viele Spalten nicht belegt, irgendwo steht ein einsames "c". Wäre es evtl. denkbar, die CSV-Dateien per Excel-VBA umzukopieren (nur Spalten, in denen Werte stehen)? Könnte dadurch das 255-Maximum nicht unterschritten werden, um dann wieder die Access-Import-Definition nutzen zu können?
Vielen Dank jedenfalls für alle, die diese lange Antwort lesen.
Grüße,
c
Hi,
Zitat von: crystal am Juli 01, 2016, 11:05:57
Wenn Access die Import-Definition auf 255 Spalten beschränkt
es geht hier nicht um eine Import-Definition sondern um die maximale Anzahl von Datenfeldern in einer Tabelle. Variante-1 ist demnach gar nicht erst umsetzbar.
Die Lösung wird vmtl. darin bestehen, die csv-Datei als Textdatei zeilenweise einzulesen und innerhalb von Access aufzusplitten.
PS:
Wenn es sich allerdings um eine Excel-Tabelle handelt, so kannst du beim Verknüpfen oder Einlesen mit der TransferSpreadsheet-Methode auch einen Bereich angeben, bspw. "A:EZ" und "FA:MN".
Hallo crystal,
ZitatÜbrigens: die Variante 2 von Ekkehard halte ich für etwas zu aufwändig, da ein solcher Datentyp mit 457 einzelnen Strings im Prinzip auch nichts anderes ist als ein String-Vektor (dim MyString(457) as string).
Wenn man eine Zeile der CSV-Datei einliest, kann man sie mit SPLIT leicht in einen solchen Vektor überführen und über dessen Elemente loopen (starten bei 0).
Was da jetzt aufwändiger ist, lass ich andere beurteilen.
Da mir aber auch nicht klar ist ob da jetzt im Höchstfall eine Auswahl von
255 Feldern in
eine Tabelle importiert werden soll, oder alle 457 Felder
in mehrere Tabellen, und wie da die Reihenfolge der Felder angelegt ist,
finde ich es so, mit "Feldnamen", einfacher diese Tabellen zu beschreiben,
als irgendwelche Verrenkungen mit abzählen zu veranstalten; - ich muss
mir einfach keine Gedanken um eine Reihenfolge zu machen.
Ich hätte aber noch eine Frage in die Runde zu meinem Code bzügl. der
Loop-Bedingung (habe das ja nicht gestestet). Hat #intDateiNr überhaupt
eine Eigenschaft EOF?
Den Code hatte ich aus einer 15 Jahre alten Prozedur zusammen gestoppelt,
wo es aber um den Import einer Textdatei mit fester DS- und Feldlänge geht.
Zudem haben die DS dort eine Kennung, an der ich die Loop-Bedingung
festmachen konnte.
Das
Do Until #intDateiNr.EOF
war also nur geraten.
Würde mich also interessieren, wie's richtig wäre.
gruss ekkehard
Hallo,
ZitatHat #intDateiNr überhaupt
eine Eigenschaft EOF?
Nein, es handelt sich bzgl. von Datei-Operationen um eine Funktion.
aus der VBA-Hilfe:
ZitatDim InputData
Open "MYFILE" For Input As #1 ' Open file for input.
Do While Not EOF(1) ' Check for end of file.
Line Input #1, InputData ' Read line of data.
Debug.Print InputData ' Print to the Immediate window.
Loop
Close #1 ' Close file.
Danke Franz,
Das hatte ich nicht gefunden. Unter welchem Begriff steht das dort?
Ich glaube, ich hatte unter "Open" geschaut. Bin da aber auch mit
Querverweisen nicht drauf gekommen.
Aber ganz verkehrt war die Idee ja nicht, nur falsche Syntax; - Korrektur:
Do Until EOF(intDateiNr)
Und, deine Einschätzung der Vorschläge?
gruss ekkehard
Vielleicht auch: Import Excel-Tabelle mit mehr als 255 Spalten (http://www.ms-office-forum.net/forum/showthread.php?t=332461)
Hallo,
zunächst würde ich die CSV-Daten analysieren und definieren, welche von den Feldern zu welchen (späteren ) Tabellen gehören müssen (--> Beachten der Normalisierungsregeln). Sodann zeilenweises Einlesen der Datei (mit Line Input, gibt aber auch andere Möglichkeiten) und Aufdröseln der Felder in ein Array (Split-Funktion) oder (vielleicht sogar besser, da anstelle eines Index-Wertes beliebige Namen verwendet werden können,) eine Collection-Auflistung.
Mit Hilfe von Recordsets (fände ich hier günstiger als direkte Anfüge-SQL-Strings, wobei eine reine SQL-Lösung auch denkbar wäre) die Collection-Elemente in die jeweiligen Tabellen (,die vorher zu erstellen sind und alle ein Autowert-ID-Feld und die restlichen Felder mit den korrekten Datentypen) haben müssen) schreiben/anfügen. Dabei kann auch der jeweilige Primärschlüssel-Wert "berechnet" und für die Fremdschlüsselfelder in anderen Tabellen (entspr. der Normalisierung) während deren "Befüllung" benutzt werden.
Das wäre meine Vorgehensweise .
Einiges könnte auch mit DDL abgedeckt werden, z. B. die Erstellung der Tabellen. Ob das im vorliegenden Fall von (zeitlichen) Vorteil wäre, kann ich so nicht beurteilen. Sinnvoll wäre es aber, wenn der Importvorgang öfters und auch mit unterschiedlicher CSV-Struktur durchgeführt werden muss.
@ekkehard
Zitatfinde ich es so, mit "Feldnamen", einfacher diese Tabellen zu beschreiben,
als irgendwelche Verrenkungen mit abzählen zu veranstalten; - ich muss
mir einfach keine Gedanken um eine Reihenfolge zu machen.
Prinzipiell denke ich: hat man die Daten in einem Vektor oder Array, das man durch-loopen kann, so kann man natürlich auch Feldnamen "dynamisch" bzw. programmtechnisch zusammensetzen (feldname = "MeinFeld"&i). Da braucht man i nicht einmal formatieren...
Eine For-Next-Schleife über z.B. 457 Felder ist doch wohl leichter zu entwickeln und zu pflegen, als 457 Zeilen mit einzelnen Zuweisungen. Immerhin wären das im Sourcecode-Ausdruck ca. 6 DIN-A-4-Seiten....
Aber egal wie man es dreht, irgendwo muss man natürlich den Aufwand treiben, so viele Tabellen- und/oder Formular-Felder zu definieren. Ich gebe allerdings zu, dass 457 einzeln benannte Felder hier den Vorteil hätten, dass deren Namen auch "sprechend" verändert werden können, als sich mit einem Lauf-Index zu beschäftigen. Nach bekannter Datenlage scheinen solch sprechende Namen aber eher nicht vorzuliegen.
Nach wie vor fände ich meine Lösung Nr. 3 am ehesten geeignet, alle möglichen Eventualitäten zu berücksichtigen.
Mich würde ja interessieren, was der TS zu den Vorschlägen sagt. Eine Rückmeldung wäre schön, damit man sich selbst überprüfen kann, ob man in die passende Richtung gedacht hat, zumal die Aussagen über die Ausgangsdaten eher knapp sind...
Denn leider muss ich feststellen, das viele Threads vom Thread-Starter nicht mehr verfolgt werden und mögliche Lösungen einer Beurteilung harren, teilweise über Wochen. Das ist sehr schade und enttäuschend, wie vielleicht auch andere meinen, die sich in die jeweilige Problematik eindenken und ihre Beiträge leisten.
Nebenbei sollte man auch immer eine Betrachtung in die Richtung führen, warum so eine - ich sag mal schwieriger zu verarbeitende - CSV-Datei überhaupt erst erzeugt wird und in Anwendung kommt.
Standardisierung und Einhalten von Standards bringt Einfachheit und Schwung in die Verarbeitung. Wenn heute immer noch jede Schraube und jede Mutter individuell von Hand geschnitzt würde, könnten sich nur die allerwenigsten ein Auto leisten (Protzwanderstock statt Protzauto).
Daher sollte man sich beim Erzeuger der CSV dafür interessieren, ob nicht auch etwas Standardgemäßes, was dann einfachst weiterzuverarbeiten ist, erzeugt werden kann. Gedankenlosigkeit und Unfähigkeit kommen durchaus nicht so selten vor, am Ende erzeugt vielleicht derjenige, der sich über die zusätzlichen Probleme ärgert und sie sowieso nicht beherrscht, selber solchen Datensalat.
Hallo crystal,
Viele Wege führen nach Rom. Wobei Eberhards sicher der kürzeste ist.
Bezügl. Rückmeldungen der TS kann ich dir nur zustimmen, finde ich
auch immer schade. Habe manchmal das Gefühl die geben zu schnell
auf, und machen dann doch mit Excel weiter.
In diesem Fall mag es auch sein, dass der TS einfach überfordert ist mit
den verschiedenen Vorschlägen und/oder sich nicht entscheiden kann,
welchen er für sich geeignet hält/weiterverfolgen soll.
gruss ekkehard
Hallo zusammen,
habe leider nicht mehr an der Diskussion teilnehmen können.
Ich bin auf Schichtarbeit und da kann man halt nicht immer Online sein.
Man muss auch mal schlafen und sich bei den Liebsten melden.
Also habe den Code mal laufen lassen:
habe den Pfad eingefügt und eine Tabelle2 erstellt.
Bricht aber ab bei :
rst.Fields("Feld1") = impRec.FELD1
mit Fehlermeldung: 3163
habe eine BMP angehängt.
Was geht denn da schief ?
Hallo nochmals Ich,
habe jetzt mal Antworten durchforstet.
Mir wäre daran gelegen eine einfache Vorgehensweise zu realisieren.
Die CSV Datei hat eine große Anzahl an Feldern von denen ich aber nur ca. 100 Felder
brauche.
Diese sollten dann in eine oder wenn nicht möglich in mehrere Access Tabellen eingefügt werden.
Diese CSV-Datei wird jeden Tag neu von eine anderen Fa. versendet und dann in dieser Access Tabelle oder Tabellen angehängt.
Daraus möchte ich dann eine Datenbank aufbauen, die man durchforsten kann.
Das wäre das Ziel !
Lade doch bitte eine gekürzte Original-Datei (sensible Daten ggf. anonymisieren) hoch und teile mit, welche Spalten (Namen, falls vorhanden bzw. Position in der Datei) für Dein Vorhaben benötigt werden. Wenn Du dann noch eine Access-Datenbank (möglichst im 2003-er Format) mit einer leeren Zieltabelle hinterlegst, findet sich bestimmt jemand, der Dir das zusammenbastelt.
Dabei könntest Du zusätzliche Denkfragen beachten:
- Eine Tabelle mit 100 Feldern?
- Wie sieht die nachfolgende Verarbeitung der Daten aus?
(Man könnte auch über ein Datenmodell statt nur Sammeltabelle(n) nachdenken.)
- Neue Daten
-- ersetzen vorhandene Daten?
-- werden einfach angefügt?
-- aktualisieren vorhandene Datensätze, nicht vorhandene werden ergänzt?
Hi,
die Datensatzstruktur sollte schon passen, mit nur sechs Feldern wirst du nicht zum Ziel kommen.
Ich hatte das auch schon mal ausprobiert mit dem Binary Input, leider ohne Erfolg.
Eine Testdatei + DB wären also hilfreich.
Apropos:
Zitateine gekürzte Original-Datei
In der Länge Ja, nur nicht in der Breite. Ein paar Zeilen genügen schon, aber es sollten schon alle Spalten enthalten sein, damit es realistisch bleibt.
Hallo,
Zitatmit Fehlermeldung: 3163
habe eine BMP angehängt.
Finde die Fehlermeldung eigentlich ausnahmsweise zielführend.
Betrachte den Tabellenentwurf und schau welchen Datentyp (am
Anfang sagtest du "alles Text") das Feld hat. Wenn es Text
ist,
stelle die Eigenschaft "Feldgrösse" auf 255.
Sollte das Feld einen anderen Datentyp haben, musst du dir die
zu importierenden Daten noch einmal anschauen, und den Typ
entsprechend anpassen, oder eine Konvertierung im Code vornehmen.
Z.B. wenn Feld1 vom Typ Zahl ist:
Zitatrst.Fields("Feld1") = VAL(impRec.FELD1)
gruss ekkehard
Habe die test Datei angehängt.
Musste diese aber als *.XLS abspeichern.
Zitat von: MaggieMay am Juli 06, 2016, 10:12:33
Hi,
die Datensatzstruktur sollte schon passen, mit nur sechs Feldern wirst du nicht zum Ziel kommen.
Ich hatte das auch schon mal ausprobiert mit dem Binary Input, leider ohne Erfolg.
Eine Testdatei + DB wären also hilfreich.
Apropos:
Zitateine gekürzte Original-Datei
In der Länge Ja, nur nicht in der Breite. Ein paar Zeilen genügen schon, aber es sollten schon alle Spalten enthalten sein, damit es realistisch bleibt.
habe den Code: "
Set rst = CurrentDb.OpenRecordset(Name:="Tabelle2")
Do Until EOF(intDateiNr)
'Do Until #intDateiNr.EOF '<- bei diesem Ausdruck bin ich nicht sicher
rst.AddNew
rst.Fields("Feld1") = impRec.FELD1
'rst.Fields("Feld2") = impRec.FELD2
rst.Update
Get #intDateiNr, , impRec
Loop
"
ausprobiert und es bricht entweder mit Fehlermeldung ab oder schreibt erst gar nicht in die Tabelle2 hinein.
Tabelle2 habe ich auf 255 zeilen eingestellt aber ohne Erfolg.
Zitat von: Lachtaube am Juli 06, 2016, 09:21:13
Lade doch bitte eine gekürzte Original-Datei (sensible Daten ggf. anonymisieren) hoch und teile mit, welche Spalten (Namen, falls vorhanden bzw. Position in der Datei) für Dein Vorhaben benötigt werden. Wenn Du dann noch eine Access-Datenbank (möglichst im 2003-er Format) mit einer leeren Zieltabelle hinterlegst, findet sich bestimmt jemand, der Dir das zusammenbastelt.
habe mal beide Dateien eingezipt.
Access und CSV Datei
Hoffe man kann damit was anfangen und man gibt mir einige Tipps wie ich die Access
VBA dazu bringe mir die CSV in die Tabelle2 zu schreiben !!??
Nachtrag: Habe versucht die Access Datei anzuhängen aber leider ist die 300 Kb ein Knackpunkt.
Es wäre mir wichtig das man aus der CSV beliebige Felder in Access importieren kann !!!
d.h. das man durch Änderung am Code weiter Felder hinzufügen kann.
das Ergebnis sollte etwa so wie in angehängter Access_Tabelle2 aussehen.
Hi,
hast du die Access-Datei komprimiert und gezippt vor dem Upload?
Zitat von: MaggieMay am Juli 08, 2016, 12:19:17
Hi,
hast du die Access-Datei komprimiert und gezippt vor dem Upload?
ja, hab es versucht bin aber dann immer noch bei 900 kB
Du solltest die Access-Datei nur auf das notwendigste reduzieren was für das aktuelle Problem gebraucht wird, d.h. Ziel-Tabelle(n) und VBA-Code.
Lege test3.csv in das Verzeichnis der Datenbank. Erstelle eine Tabelle Data mit den Feldern: Zeitpunkt (Datum/Uhrzeit), Position (Zahl, Integer), Wert (Zahl, Double).
Begib Dich in den VBA-Editor und erstelle ein neues allgemeines Modul und füge folgende Zeilen ein.
Public Sub ImportCSV()
Const FILENAME$ = "\test3.csv"
Const HDRLINE$ = "Datum;"
Const NOHDR$ = "Keine Überschriftenzeile gefunden"
Dim f%, l$, GotHdr As Boolean, rs As DAO.Recordset
f = FreeFile()
Open CurrentProject.Path & FILENAME For Input As #f
Do Until EOF(f) Or GotHdr
Line Input #f, l
GotHdr = Left$(l, 6) = HDRLINE
Loop
If Not GotHdr Then
MsgBox NOHDR
Else
Set rs = CurrentDb().OpenRecordset("Data", dbOpenTable)
Do Until EOF(f)
Line Input #f, l
Call ProcessLine(rs, l)
Loop
rs.Close
End If
Close #f
End Sub
Private Sub ProcessLine(rs As DAO.Recordset, l$)
Const SEPARATOR$ = ";"
Dim s$(), dt, i&
On Error GoTo 1
s = Split(l, SEPARATOR)
dt = CDate(s(0) & " " & s(1))
For i = 2 To UBound(s) Step 4
rs.AddNew
rs.Collect("Zeitpunkt") = dt
rs.Collect("Position") = i + 1
rs.Collect("Wert") = CDbl(s(i))
rs.Update
Next
1
End Sub
Wenn Du dann die Tastenkombination Strg-G drückst, öffnet sich das Direktfenster. Trage dort ImportCSV ein und drücke die Eingabetaste - die Daten sollten danach in der erstellten Tabelle vorliegen. Die Position weist die Spaltennummer des Werts aus - interpretieren musst Du ihn selbst (ggf. über eine entsprechende Bedeutungstabelle referenzieren).
Zitat von: MaggieMay am Juli 08, 2016, 12:33:07
Du solltest die Access-Datei nur auf das notwendigste reduzieren was für das aktuelle Problem gebraucht wird, d.h. Ziel-Tabelle(n) und VBA-Code.
unter 804 Kb geht es bei der Access Datei nicht ?!
Wie gesagt, nur das allernotwendige für das Import-Problem. Was meinst du könnte das sein? Welche und wie viele Objekte beinhaltet die DB, die du hochzuladen versuchst?
Hast du sie vor dem Zippen mit den Datenbanktools komprimiert?
Zitat von: MaggieMay am Juli 08, 2016, 13:19:33
Wie gesagt, nur das allernotwendige für das Import-Problem. Was meinst du könnte das sein? Welche und wie viele Objekte beinhaltet die DB, die du hochzuladen versuchst?
Hast du sie vor dem Zippen mit den Datenbanktools komprimiert?
Hallo Hallo,
habe den Code ausprobiert ! :)
Das flutsch super !!!
DANKE SCHÖN !
Auch das mit der Position ist super.
Bin halt keine Access Man/Frau
Werde den Code morgen in der Frühschicht noch weiter bearbeiten.
Ich muss immer die neuste Test-Datei= test_20160707_20160708
an die schon vorhanden in Access anhängen.
Hatte mir das so zusammen gestrickt:
Debug.Print TxtDatum
Datum = Str(Date)
Debug.Print Datum
Datum = Format(Date, "yyyymmdd") ' heutiges Datum als Text z.B.: 20160622
Debug.Print Datum
DatTyp = ("Test*" & Datum & ".csv")
'Const DatTyp = "Test*.csv"
Const SuchVerzeichnis = "I:\ORG\OPOTSS\Dispatching\Zaehlerstaende_Epe\"
AktDatei = Dir(SuchVerzeichnis & "\" & DatTyp)
While Len(AktDatei) > 0
Debug.Print AktDatei
Werde das morgen in der Frühschicht mal das schreiben.
Danke nochmals !!!!
Vermutlich gehört noch ein Kunden bzw. besser ein Zählerbezug zu den Daten. Die Daten sind zumindest in der Testdatei ausgeXt, weswegen ich das außen vor gelassen habe.
Kunde [--hat 0..n--> Zähler;
Zähler [--hat 0..n--> Ablesungen;
Zitat von: Lachtaube am Juli 08, 2016, 13:59:36
Vermutlich gehört noch ein Kunden bzw. besser ein Zählerbezug zu den Daten. Die Daten sind zumindest in der Testdatei ausgeXt, weswegen ich das außen vor gelassen habe.
Kunde [--hat 0..n--> Zähler;
Zähler [--hat 0..n--> Ablesungen;
Ja, in:
Zeile 4: Datenkanal: NotXXXXXXXXtrom-DieXXXXXXXXel Anzahl XXXXXXXXtartXXXXXXXX
Könntest du mir noch einen Hinweis geben wie ich das in die Tabelle2 einfügen könnte ?
Dazu müssten die Daten im Kopfbereich schon etwas realistischer sein. Ich kann mit dem geXe leider wenig anfangen.
Hallo,
habe jetzt den Code so angepasst das er mir die aktuelle Datei einliest.
Diese Test Dateien habe ich per Outlook in einen Unterordner verschoben immer dann wenn eine neue Email eintrudelt.
Werde dann noch zwei Button machen die mir die aktuelle Datei oder alle Dateien einliest.
Soweit so schön !
Ich habe da noch eine Frage:
neben dem Wertepaar das immer unter den Titel: Werte steht
ist auch noch ein Status (K,P,C) abzufragen das rechts neben dem Wert steht.
Dieser Status ist wichtig um zu beurteilen ob die Werte OK sind.
siehe Unten:
Wert Status
11465102
11465102
11465102
11465102
11465102
11465102
11465102
11465102
11465102 K
11465102
11465102
11465102
11465102
11465102
11465102
11465102
11465102
11465102
11465102
11465102
11465102
11465102
11465102
11465102
wie kann ich dieses auslesen des Status (K,P,C) in den Code integrieren.
PS: Sorry für das XXX
Kann ich einen Teil der CSV ohne XXX anfügen ?
Dann kann man vielleicht den Code so anpassen das man die Zeile 4 noch in die Tabelle2 hinein bekommt.
Gruß von der Frühschicht
Habe jetzt den Code so ein bisschen verstanden.
Es wird die Stelle gesucht wo das Datum steht.
Dann wird die Zelle darunter abgesucht nach Zeichenketten oder Werte.
Wenn was gefunden wurde wird die Zeile in die Tabelle= data geschrieben.
Immer pro Stundenwert 7:00,8:00,9:00 u.s.w.
Es wiederholt sich so lange bis EOF.
Komme ich dem ein bisschen nahe ?
Habe aber keine Ahnung wie man die CSV_ zeile 4=Datenkanal: mit der Position_data verbinden kann ?
Zitat von: Lachtaube am Juni 30, 2016, 23:21:34
Hi,
die gezeigten Daten lassen leider ein sinnvolles Modellieren für einen Nicht-Esoteriker nicht zu.
CSV-Dateien lassen sich mit der Open (https://is.gd/PQYa90)-Anweisung öffnen. Nach dem Öffnen kann man Zeile für Zeile der Datei einlesen (Line Input # Statement (https://is.gd/K8BfiU)). Eine Zeile könnte man in ein Datenfeld (Array) aufsplitten (Split Function (https://is.gd/fumIx4)) und die gewünschten Inhalte (über entsprechende Recordset(s) oder auch Anfügeabfrage(n)) in einen oder mehrere neue Datensätze schreiben. Am Ende schließt man die Datei wieder (Close Statement (https://is.gd/RuufuD)).
Dieses Verfahren wird in Programmiersprachen allgemein als Parsen bezeichnet.
Ja, genau Split Verfahren:
Muss ich noch viel dazu lernen.
Bin dran den Code Schritt für Schritt aufzudröseln damit man was fürs Leben mit nehmen kann.
PS: Esoterik ohne Alkohol ist kaum auszuhalten, genau wie Access ohne Basic-Wissen.
aber genug der Klugschnackerei ! :)
Habe heute fertig, dann bis zur nächsten Frühschicht !! :) 8)
Zum Status: füge ein Textfeld mit der Feldgröße 1 der Tabelle zu und nenne es Status.
Zum Datenkanal musst Du schon konret werden - ich bin kein Hellseher. Deshalb habe ich nur einen Methoden-Rumpf dazu erstellt. Diesmal ungetestet, weil das Beispiel keine Status-Daten enthält.
Public Sub ImportCSV()
Const FILENAME$ = "\test3.csv"
Const HDRLINE$ = "Datum;"
Const DATENKANALLINE$ = "Datenkanal:;"
Const NOHDR$ = "Keine Überschriftenzeile gefunden"
Dim f%, l$, GotHdr As Boolean, rs As DAO.Recordset
f = FreeFile()
Open CurrentProject.Path & FILENAME For Input As #f
Do Until EOF(f) Or GotHdr
Line Input #f, l
GotHdr = Left$(l, 6) = HDRLINE
If Left$(l, 12) = DATENKANALLINE Then ProcessDatenKanalLine(l)
Loop
If Not GotHdr Then
MsgBox NOHDR
Else
Set rs = CurrentDb().OpenRecordset("Data", dbOpenTable)
Do Until EOF(f)
Line Input #f, l
Call ProcessLine(rs, l)
Loop
rs.Close
End If
Close #f
End Sub
Private Sub ProcessLine(rs As DAO.Recordset, l$)
Const SEPARATOR$ = ";"
Dim s$(), dt, i&
On Error GoTo 1
s = Split(l, SEPARATOR)
dt = CDate(s(0) & " " & s(1))
For i = 2 To UBound(s) Step 4
rs.AddNew
rs.Collect("Zeitpunkt") = dt
rs.Collect("Position") = i + 1
rs.Collect("Status") = IIf(Len(Trim$(s(i +1))) = 1, Trim$(s(i +1)), Null)
rs.Collect("Wert") = CDbl(s(i))
rs.Update
Next
1
End Sub
Private Sub ProcessDatenKanalLine(l$)
' Hier die Datenkanalzeile auswerten
End Sub
Hallo Guten Morgen,
habe das mit den Status eingefügt und klappt super :) 8), Danke nochmals !!
Habe eine *.jpeg angefügt darin sieht man wie das mit dem Datenkanal aussehen soll.
Die Daten habe ich händisch eingefügt damit man sieht was ich damit will.
Wenn das klappt wäre ich sehr froh. ;D
Gruß aus dem sonnigen Norden !!
Wie leicht zu erkennen ist, sollten die Angaben des Datenkanals in einer separaten Tabelle ablegt werden, denn diese spiegeln ja die Position der Werte wieder. Statt einer Position würde in der Data-Tabelle dann ein Fremdschlüssel dieser Tabelle stehen.
Wie schon vorher angedeutet: aus dem geXe baue ich kein weiteres Beispiel. :(
Schönen Sonntag Lachtaube,
habe die die Test5 Datei als zip angehängt.
Habe die Sache nicht mehr aus gext sondern
anders benannt.
Hoffe du kannst mit dem was anfangen.
Es ist ja klar dass man aus rudimentären Dateien keine Wunderwerk extrahieren kann.
Also hoffe und Glaube !
Schau mal, ob das so genügt.
Moin Hallo,
habe die Datei getestet.
Mit der test5.csv klappt es prima
aber mit der Orginal Datei sagt er mir:
Fehlernr_2147221501
Fehler beim verarbeite der Datenkanalzeile.
Wenn ich in die Tabelle"Datenkanal" schaue hat er das ganz prima ausgefüllt.
So wie es aussieht findet er keine Ende und bricht dann mit der Fehlermeldung ab.
Unter der Tabelle "Kunde" hat er mir einen Kundennamen angelegt.
habe die *.jpeg angehängt.
Ich kann nur von Fakten ausgehen, die mir vorliegen. Wenn Du nicht mehr Informationen liefern kannst, musst Du selbst versuchen, strukturelle Unterschiede zwischen dem Beispiel und dem Original in der Datenkanalzeile zu ermitteln.
PS: Riesen-Screenshots sind einer Problemlösung kaum dienlich. ???
Hallo,
ja richtig !
Habe jetzt den Code durchlaufen lassen:
Der Abruck kommt bei
Private Function ProcessDatenKanalLine(db As DAO.Database, l$)
der Abbruch kommt bei
If .NoMatch = Wahr
und dann wenn er versucht das : .Update
zu machen.
siehe auch *.jpg<<< diesmal mit mehr Aussagekraft
Grüße von der Spätschicht !!!
Ich vermute eher, dass Du das Beispiel in der Zeile Datenkanal: beim Editieren vergeigt hast - prüfen musst Du das selbst. Oder gibt es auch leere Positionen in der Zeile?
Und noch einmal: anhand von Screenshots kann ich Dir nicht helfen. Der Fehler liegt vermutlich in einer unterschiedlich aufgebauten Datenkanal-Zeile.
Hallo schönen Abend,
es gibt in der Zeile Datenkanal: auch leere Positionen !
Habe nicht verstanden was ich vergessen haben soll !
Die Zeile habe ich nochmal mit dem Original verglichen und sind bis auf die
Buchstaben in der Zeile (die habe ich geändert) gleich.
Wenn der Code durchläuft dann wird In der Schleife alles in die Tabelle: Datenkanal
geschrieben.
Bis die Schleife verlassen werden soll, dann ist die Fehlermeldung da.
Bei direkter Antwort sind komplette Zitate überflüssig, verlängern nur unnötig das Thema. Zitat daher gelöscht. MzKlMu
Würden in dieser Zeile Betriebsgeheimnisse stehen, hätte ich ja Verständnis für das Zurückhalten der Information.
Das Ratespiel geht weiter. Neuer VorschlagPrivate Function ProcessDatenKanalLine(db As DAO.Database, l$)
Const ERRMSG$ = "Fehler beim Verarbeiten der Datenkanalzeile"
Dim s$(), i&, varr
On Error GoTo 1
s = Split(l, SEPARATOR)
ReDim varr(UBound(s))
'// ist das auch im Original so ?????
s(2) = s(1) '// 1. Eintrag tanzt aus der Reihe => korrigieren
With db.OpenRecordset("DatenKanal", dbOpenTable)
.Index = "unique_dk"
For i = 2 To UBound(s) Step 4
If Len(Trim$(s(i))) Then
.Seek "=", Trim$(s(i))
If .NoMatch Then
.AddNew
.Collect("DatenKanal") = Trim$(s(i))
.Update
.Bookmark = .LastModified
varr(i) = .Collect("DatenKanalId")
Else
varr(i) = .Collect("DatenKanalId")
End If
End If
Next
.Close
End With
ProcessDatenKanalLine = varr
Exit Function
1
Err.Raise vbObjectError + &H3, "mdlImport.ProcessDatenKanalLine", ERRMSG
End Function
Es wird dann nur importiert, was auch eine Eintragung im Datenkanal hat.Private Sub ProcessLine(rs As DAO.Recordset, id&, arr, l$)
Dim s$(), dt, i&
On Error GoTo 1
s = Split(l, SEPARATOR)
dt = CDate(s(0) & " " & s(1))
For i = 2 To UBound(s) Step 4
If Len(Nz(arr(i))) Then
rs.AddNew
rs.Collect("KundenId") = id
rs.Collect("DatenKanalId") = arr(i)
rs.Collect("Zeitpunkt") = dt
rs.Collect("Wert") = CDbl(s(i))
rs.Collect("Status") = IIf(Len(Trim$(s(i + 1))) = 1, Trim$(s(i + 1)), Null)
rs.Update
End If
Next
1
End Sub
Hallo zusammen,
habe was gefunden !! :)
Wenn ich die Daten der Orginal-Datei in die Test5 Datei kopiere dann,
ja dann, funktioniert der Code von Lachtaube ?
Warum den dass ??
8) :P
Zitat von: Lachtaube am Juli 11, 2016, 18:32:02
Ich vermute eher, dass Du das Beispiel in der Zeile Datenkanal: beim Editieren vergeigt hast - prüfen musst Du das selbst. Oder gibt es auch leere Positionen in der Zeile?
Und noch einmal: anhand von Screenshots kann ich Dir nicht helfen. Der Fehler liegt vermutlich in einer unterschiedlich aufgebauten Datenkanal-Zeile.
:D :D :D :D :D :D :D :D :D :D :D :D
ES FUNZT !!!! 8) 8) 8) 8) 8)
Das war der Durchbruch !!
DANKE FÜR DIE UNTERSTÜTZUNG !!
Moin Moin,
schöne Grüße aus der Spätschicht.
Habe ein Frage zu dem Programm.
Das Programm läuft super, nur muss ich jetzt eine Erweiterung machen.
Es soll ein Formular aus der Zeit 6:00 Uhr von gestern bis 6:00 Uhr von Heute erstellt werden.
Die einzelnen Datensätze sind immer die selben und sollen in das Formular übernommen werden.
Es sollen dann die einzelnen Datensätze angeordnet werden.
Wenn das Formular erstellt ist dann soll es als Excel Datei exportierbar sein.
Frage: Wie bekomme ich es hin das ich einen Abfrage Assistenten einbaue wo ich die Anfangszeit(6:00 gestern) und Endzeit(6:00 Uhr heute) für das neue Formular einstellen kann ?
Wie kann ich einen Schalter (Button) bauen der mir aus dem neuen Formular eine Excel Datei erzeugt ?
Grüße aus der Spätschicht !
Macht es einen Unterschied für die Bestimmung des Datums, den Export morgens um 4 Uhr oder um 7 Uhr anzuleiern?
Im Prinzip muss nur ein Datum für ein Abfragekriterium erfragt (eingegeben) werden, welches Deine Daten einschränkt. Dabei gilt: [DeinZeitfeld] >= [Datumskriterium] + #06:00:00# Und [DeinZeitfeld] < [Datumskriterium] + 1 + #06:00:00#
Das Kriterium kann dann entweder als Formularparameter in einer gespeicherten Abfrage oder als Funktion (http://www.donkarl.com/FAQ/FAQ3TAbfragen.htm#3.15) verankert werden. Mit DoCmd.Transferspreadsheet (https://msdn.microsoft.com/de-de/library/office/ff844793.aspx) ließe sich anschließend ein Excel-Export anstoßen.
Moin,
Habe jetzt erst das lesen können.
Es muss immer von 6:00 Uhr bis 6:00 Uhr also die 24 Stunden dazwischen in das Formular eingetragen werden.
Ich brauche also ein Zeitfeld als Eingabemaske in einer Abfrage oder ?
Werde mal schauen ob ich das in einer Abfrage einbauen kann ?
Melde mich wieder !!
Gruß Helmut
Helmut, Du musst nur ein Datum als Parameter festlegen, zu dem dann für den unteren Grenzwert 6 Stunden bzw. für den oberen Grenzwert 1 Tag + 6 Stunden hinzuaddiert werden (genauso wie in meiner skizzenhaften Erklärung in vorherigen Beitrag).
Moin Moin,
habe es verssucht aber leider ohne Erfolg.
Wenn ich unter Kriterium das eingeben dann wird leider kein Datensatz angezeigt.
kann man das ganze nicht in die VBA Abfrage einbauen die du mir damals zusammen gestellt hast.Public Sub ImportCSV_1()
Const ZielTab = "Zaehlerstaende"
Dim i As Integer
Dim AktDatei As String
Dim TxtDatum As String
' Dim f%, l$, GotHdr As Boolean, rs As DAO.Recordset
Const FILENAME$ = "\test3.csv"
Const HDRLINE$ = "Datum;"
'Const NOHDR$ = "Keine Überschriftenzeile gefunden"
Const SuchVerzeichnis$ = "I:\ORG\OPOTSS\Dispatching\Zaehlerstaende_Epe\"
'Datum in Text umwandeln
Debug.Print TxtDatum
Datum = Str(Date)
Debug.Print Datum
Datum = Format(Date, "yyyymmdd") ' heutiges Datum als Text z.B.: 20160622
Debug.Print Datum
DatTyp = ("Test*" & Datum & ".csv")
AktDatei$ = Dir(SuchVerzeichnis & "\" & DatTyp)
'CurrentDb.Execute "DELETE * FROM Gastag_Gesamt" ' lösche der Daten in Tabelle: Gastag_Gesamt
'Const FILENAME$ = "\test5.csv"
Const KUNDENLINE$ = "Kundenname:;"
Const DATENKANALLINE$ = "Datenkanal:;"
' Const HDRLINE$ = "Datum;"
Const NOHDR$ = "Keine Überschriftenzeile gefunden"
Dim f%, kid&, kdarr, l$, GotHdr As Boolean
Dim db As DAO.Database, rs As DAO.Recordset
On Error GoTo 1
f = FreeFile()
Open SuchVerzeichnis & AktDatei For Input As #f
'Open CurrentProject.Path & FILENAME For Input As #f
Set db = CurrentDb()
Do Until EOF(f) Or GotHdr
Line Input #f, l
If Left$(l, 12) = KUNDENLINE Then kid = ProcessKundenLine(db, l)
If Left$(l, 12) = DATENKANALLINE Then kdarr = ProcessDatenKanalLine(db, l)
GotHdr = Left$(l, 6) = HDRLINE
Loop
If Not GotHdr Then
MsgBox NOHDR
Else
Set rs = CurrentDb().OpenRecordset("AbleseDaten", dbOpenTable)
Do Until EOF(f)
Line Input #f, l
Call ProcessLine(rs, kid, kdarr, l)
Loop
rs.Close
End If
0
Close #f
Exit Sub
1
MsgBox Err.Description & vbCrLf & vbCrLf & "Fehler-Nr.: " & Err.Number, _
vbExclamation, "CSV-Import Fehler"
Resume 0
End Sub
Private Sub ProcessLine(rs As DAO.Recordset, id&, arr, l$)
Dim s$(), dt, i&
On Error GoTo 1
s = Split(l, SEPARATOR)
dt = CDate(s(0) & " " & s(1))
For i = 2 To UBound(s) Step 4
If Len(Nz(arr(i))) Then
rs.AddNew
rs.Collect("KundenId") = id
rs.Collect("DatenKanalId") = arr(i)
rs.Collect("Zeitpunkt") = dt
rs.Collect("Wert") = CDbl(s(i))
rs.Collect("Status") = IIf(Len(Trim$(s(i + 1))) = 1, Trim$(s(i + 1)), Null)
rs.Update
End If
Next
1
End Sub
Private Function ProcessKundenLine(db As DAO.Database, l$)
Const ERRMSG1$ = "Es befinden sich keine Kundendaten in der Datei"
Const ERRMSG2$ = "Fehler beim Verarbeiten des Kundennamen"
Const SELQRY$ = _
"SELECT KundenId, KundenName, KundenVorname" & _
" FROM Kunde WHERE KundenName = [@KundenName];"
Dim s$(), k$
On Error GoTo 1
s = Split(l, SEPARATOR)
k = Trim$(s(1))
If Len(k) = 0 Then
Err.Raise vbObjectError + &H1, "mdlImport.ProcessKundenLine", ERRMSG1
End If
With db.CreateQueryDef(vbNullString, SELQRY)
.Parameters("@KundenName") = k
With .OpenRecordset(dbOpenDynaset)
If Not .EOF Then
ProcessKundenLine = .Collect("KundenId")
Else
.AddNew
.Collect("KundenName") = k
.Update
.Bookmark = .LastModified
ProcessKundenLine = .Collect("KundenId")
End If
.Close
End With
End With
Exit Function
1
Err.Raise vbObjectError + &H2, "mdlImport.ProcessKundenLine", ERRMSG2
End Function
Private Function ProcessDatenKanalLine(db As DAO.Database, l$)
Const ERRMSG$ = "Fehler beim Verarbeiten der Datenkanalzeile"
Dim s$(), i&, varr
On Error GoTo 1
s = Split(l, SEPARATOR)
ReDim varr(UBound(s))
'// ist das auch im Original so ?????
s(2) = s(1) '// 1. Eintrag tanzt aus der Reihe => korrigieren
With db.OpenRecordset("DatenKanal", dbOpenTable)
.Index = "unique_dk"
For i = 2 To UBound(s) Step 4
If Len(Trim$(s(i))) Then
.Seek "=", Trim$(s(i))
If .NoMatch Then
.AddNew
.Collect("DatenKanal") = Trim$(s(i))
.Update
.Bookmark = .LastModified
varr(i) = .Collect("DatenKanalId")
Else
varr(i) = .Collect("DatenKanalId")
End If
End If
Next
.Close
End With
ProcessDatenKanalLine = varr
Exit Function
1
Err.Raise vbObjectError + &H3, "mdlImport.ProcessDatenKanalLine", ERRMSG
End Function
Na Ja,
keine Antwort ist auch eine Antwort.
Hallo Helmut,
Mit solchen Äusserungen solltest du vorsichtig sein. Diese verhelfen
oft zu keiner Hilfe.
Alle, die hier helfen, machen das freiwillig. Und obwohl auch einige Rentner
darunter sind ;), gibt es auch solche, die, viellecht wie du, Schichtarbeit
verrichten müssen, und deshalb vielleicht nicht mal eben über Nacht deinen
Code analysieren können.
gruss ekehard
Zusätzlich: Wenn man womöglich ein 60-Beiträge-Thema vollständig durchlesen muss, um eine Antwort in die gewünschte Richtung geben zu können, so ist das dann auch nicht ermutigend.
Gerne versteht man Aufgabe und vorhandene Umgebung sofort, um sich eine Meinung zu bilden.
Moin zusammen,
Habe es so auch jetzt aufgenommen.
Aber wenn man im Forum keinerlei Antwort von den Leuten bekommt die man zuletzt angeschrieben hat dann ist das nicht so dolle.
Auch wenn man ein Thema über lange Zeit abarbeitet !
Alle sind in dieser Zeit Busy und der Herzschlag nicht immer bei 60 bis 80 Bpm.
Die Antworten waren bis jetzt auch positiv und manchmal auch hilfreich.
Man sollte aber denjenigen schon seine Meinung über das Forum mitteilen und nicht vorsichtig oder verhalten sein. Es gibt schon zu viele Foren die sich mit ihrem eigenem EGO beschäftigen. 8)
Glück Auf !