Neuigkeiten:

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

Mobiles Hauptmenü

Teile einer CSV Datei in Access Formular einfügen

Begonnen von Sproket_1972, Juni 30, 2016, 18:06:37

⏪ vorheriges - nächstes ⏩

Sproket_1972

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

MaggieMay

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.
Freundliche Grüße
MaggieMay

Lachtaube

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).
Grüße von der (⌒▽⌒)

Sproket_1972

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 ?!

MaggieMay

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?
Freundliche Grüße
MaggieMay

Sproket_1972

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 !!!!

Lachtaube

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;
Grüße von der (⌒▽⌒)

Sproket_1972

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 ?

Lachtaube

Dazu müssten die Daten im Kopfbereich schon etwas realistischer sein. Ich kann mit dem geXe leider wenig anfangen.
Grüße von der (⌒▽⌒)

Sproket_1972

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

Sproket_1972

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 ?

Sproket_1972

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-Anweisung öffnen. Nach dem Öffnen kann man Zeile für Zeile der Datei einlesen (Line Input # Statement). Eine Zeile könnte man in ein Datenfeld (Array) aufsplitten (Split Function) 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).

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)

Lachtaube

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
Grüße von der (⌒▽⌒)

Sproket_1972

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 !!

Lachtaube

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. :(
Grüße von der (⌒▽⌒)