Datenimport aus CSV-Datei

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Antworten
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1930
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

Datenimport aus CSV-Datei

Beitrag von Rolf Ramacher »

der Datenimport funktioniert nicht ganz richtig. Die Daten werden nicht korrekt gelesen und dadurch versetzt übertragen.

Code: Alles auswählen

	do while lWeiter = .t.
		If File("sprinterscandata.csv")
			oDlg:show()
			oStatic:show()

			use Spstamm New
			Set index to "spstamm.cdx"
			Spstamm->(OrdSetFocus("artikel"))

			use Mde New Exclusive

			cDatei:=memoread("sprinterscandata.csv")
			cDatei:=strtran(cDatei,";"," ;")
			nZeile:=MLcount(cDatei,30)
msgbox(var2lchar(nzeile))
			For i = 1 to nZeile
				cDatenSatz:=alltrim(MemoLine(cDatei,30,i))
				nZaehler++
				If nZaehler % 50 == 0
					oAStatic:setcaption("Übertragung läuft:  "+cDatenSatz)
					nZaehler:=0
				Endif

				cFil:=Token(cDatenSatz,";",1)
msgbox(cfil)
				If cFil="Filiale"
				Else
					cReg:=Token(cDatenSatz,";",2)
					cMe:=Token(cDatenSatz,";",3)
					cCode:=Token(cDatenSatz,";",4)
msgbox(creg)
msgbox(cme)
msgbox(ccode)

					If Len(cCode) = 12
						cArtnr:=substr(cCode,1,9)
						If Spstamm->(DbSeek(cArtnr))
							cRestCode:=cCode
							cCode:=Spstamm->Spz+cRestcode
						Endif
					Endif
					cEintrag:="10"+cFil+dtoc(date())+cReg+cCode
					Mde->(DbAppend())
					Mde->Mde:=cEintrag
				Endif
			Next i
			FRename("sprinterscandata.csv","sprinterscandata"+cDatFile+".csv")
			oDlg:hide()
			oStatic:hide()
			Close Data
		Endif
		If File("autominvmobilende.txt")
			lWeiter:=.f.
		Endif
		sleep(1000)
	Enddo

So sieht die Datei zum testen aus. Die anzahl der Datensätze ist natürlcih unterschiedlich. wie mache ich das richtig.??

Code: Alles auswählen

Filiale;Regalnummer;Menge;Bar-Code
01;002;1;4049484767074
01;002;1;4051199073081
01;002;1;111000001079
01;002;1;130000002305
01;002;1;130000002282
01;002;1;130000002275
01;002;1;130000002268
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Datenimport aus CSV-Datei

Beitrag von brandelh »

MLCOUNT() wird bei einigen tausend Datensätzen sehr langsam !
Einige der Funktionen sagen mir nichst und wo genau das Problem liegt - also was falsch ist - steht auch nicht da ;-)

Für das zeilenweise einlesen gibt es zwei Funktionen von mir in der Wissensbasis:
:arrow: http://www.xbaseforum.de/viewtopic.php?f=16&t=7961 - sehr schnell, Größe egal
:arrow: http://www.xbaseforum.de/viewtopic.php?f=16&t=4268

Bei der zweiten Fundstelle gibt es die Funktion TxtFile2Array(cDateiName,cConvert)
solange die Anzahl der Zeilen so unter 1000 bleibt (10.000 sollten auch gehen) kann man
diese Funktion nutzen um eine Zeile in ein Array zu bekommen.
Der Vorteil liegt darin, dass Array Aktionen jedem bekannt sind.
Wenn die Dateigröße unbegrenzt sein soll, dann ist der erste LINK dein Freund :wink:

Die zweite Funktion der 2. Fundstelle enthält die Funktion Txt2Array(cDateiInhalt,cDelim)
mit der man eine CSV-Textzeile bequem in ein Array aufteilen kann, damit sollte die weitere Verarbeitung leicht sein.

Bei Pablo gibt es einen schnelleren Tokenizer() aber für die paar Daten reicht meiner auch ;-)
Gruß
Hubert
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1930
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Datenimport aus CSV-Datei

Beitrag von Rolf Ramacher »

Hallo Hubert,

danke für deinen Tipp - funkt.soweit. TxtFile2array habe ich genommen. Eine Frage aber noch. er gibt zurück eindemensionales Array aber mit nur einem Element, da stehen die entsprechenden Werte aus der CSV-Datei drin - mit komma getrennt. Ist das so gewollt ?
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Datenimport aus CSV-Datei

Beitrag von brandelh »

Nein, normalerweise eine Zeile => ein Array Element.
Kann es sein, dass deine Datei von UNIX kommt und kein CRLF sondern nur ein CR in der Datei hat ?

Zeig doch mal deine Umsetzung.
Gruß
Hubert
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1930
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Datenimport aus CSV-Datei

Beitrag von Rolf Ramacher »

Hi Hubert

ich habe dir die csv per pn sendet
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Datenimport aus CSV-Datei

Beitrag von brandelh »

Hallo Rolf,

In dem Beispielprogramm habe ich zuerst die Datei nach dem ZEILEN-Trenner durchsucht.
Bei Windows / DOS ist CRLF (chr(13)+chr(10) normal, deine Datei hat nur chr(10).

Deine CSV Datei stammt sicher von einem MAC oder UNIX Rechner (welcher genau weiß ich nicht mehr),
daher kann weder MLCOUNT() noch meine Funktion TxtFile2Array() direkt damit umgehen.
Meine Klasse HBTextReader() (erster LINK) würde das automatisch berücksichtigen, aber Funktionen sind dir sicher lieber ;-)

Hier nun mein Beispielprogramm mit der Aufteilung in einzelne Felder, das kannst du dann einfach in dein Programm übertragen.

Code: Alles auswählen

#include "Gra.ch"
#include "Xbp.ch"
#include "Common.ch"
#include "Inkey.ch"
#define CRLF chr(13)+chr(10)

procedure main()
   local cF, cBuffer, aData, aFelder, x, i, nRecAnz, cZeilenTrenner

   cF      := "sprinterscandata.csv"
   cBuffer := memoread(cF)

   ? "Zunächst testen auf richtige CRLF "
   ?
   do case
      case CRLF $ cBuffer
           cZeilenTrenner := CRLF
           ? "CRLF trennt die Zeilen"
      case chr(13) $ cBuffer
           cZeilenTrenner := chr(13)
           ? "CR trennt die Zeilen"
      case chr(10) $ cBuffer
           cZeilenTrenner := chr(10)
           ? "LF trennt die Zeilen"
      otherwise
           ? "KEIN Zeilentrenner erkannt"
   end
   ?
   ? "Wie man sieht enthält die Datei NUR LF (chr(10) !"
   ? "Das geht nicht mit der Standardfunktion !"
   ?
   aData := Txt2Array( cBuffer, cZeilenTrenner ) // Datenzeilen einlesen !

   nRecAnz := len(aData)
   ? "Anzahl Datensätze:    ",nRecAnz

   for x := 1 to nRecAnz
       // Zeile für Zeile in Felder aufteilen, "," verwenden wie in deinem Beispiel
       aFelder := Txt2Array( aData[x] , "," ) // ";" ist eigentlich sicherer, da seltener
       if aFelder[1] = "Filiale"
          ? "Feldnamen:",aFelder
       else
          ? "Inhalt:     ",aFelder
          ? "Filiale:    ",aFelder[1]
          ? "Regalnummer:",aFelder[2]
          ? "Menge:      ",aFelder[3]
          ? "Bar-Code:   ",aFelder[4]
       endif
   next

   inkey(20)

return


*-------------------------------------------------------------------------------
FUNCTION Txt2Array(cDateiInhalt,cDelim)
   local aZeilen := {}, nVon, nBis, cTxt
   DEFAULT cDelim TO CRLF
   nVon := 1
   nBis := 0
   if ! empty(cDateiInhalt)
      do while .t.
         nBis := at(cDelim,cDateiInhalt,nVon)
         if nBis = 0    // Ende der Datei wurde erreicht, letzten Satz nicht vergessen
            cTxt := substr(cDateiInhalt,nVon)
            nVon := len(cDateiInhalt)+1
         else
            cTxt := substr(cDateiInhalt,nVon,nBis-nVon)
            nVon := nBis+len(cDelim)
         endif
         cTxt := strTran(cTxt,CRLF,"")                // entferne die CRLF am Zeilenende
         aadd(aZeilen,cTxt)
         if nVon > len(cDateiInhalt)
            exit
         endif
      enddo
   endif
return aZeilen

Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Datenimport aus CSV-Datei

Beitrag von brandelh »

var2lchar() ist mit Vorsicht zu geniesen, da die Umwandlung in LOKALE Sprachoptionen nicht immer sinnvoll sind.
var2char() zeigt den Inhalt wie er ist !
memowrit() darf man nicht verwenden wenn man Texte geändert abspeichern will, da es ein chr(26) anhängt (binärdaten ist noch schlimmer).
Dafür gibt es hier oder in den Tools Str2File() oder so ähnlich.
Gruß
Hubert
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1930
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Datenimport aus CSV-Datei

Beitrag von Rolf Ramacher »

Hi Hubert,

du das kann gut sein, das es nur CR ist - die CSV-Datei kommt von einer App -ich werde das mal testen. danke dir erstmal
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1930
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Datenimport aus CSV-Datei

Beitrag von Rolf Ramacher »

Hallo Hubert,

danke klappt alles
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
Antworten