CSV -> MDB mit Hindernissen

22/02/2008 - 20:49 von Thomas Hübner | Report spam
Hi All,

Ich versuche Stück für Stück meine Machwerke aus der VB6 Zeit auf vb.NET
umzusetzen. Dabei möchte ich natürlich den Code komplett überarbeiten
und NET ausreizen. Besonders die Datatables könnten bei diesem Problem
sehr hilfreich sein.

Es gilt auf tàglicher Basis ein CSV File in eine MDB zu importieren.

Problem1: Das CSV File ist korrupt (sporadisch tauchen CRLF auf)
Problem2: Jeder Datensatz enthàlt ein Datum im Ami Format MM/DD/YYYY
Problem3: Das CSV File enthàlt zum Großteil Datensàtze, die in der DB
schon vorhanden sind und ignoriert werden müssen.
Problem4: Wàhrend des Import müssen 3 zusàtzliche Felder errechnet werden.

zu Problem2: Die CRLF kommen zum Glück innerhalb von 6 verschiedenen
immer gleichen Mustern. Meine Lösung in VB6 ist, für jedes der
Fehlmuster eine Konstante und eine Konstante mit dem korrekten Muster.
Nach dem einlesen der kompletten CSV als string führe ich ein Replace
aller 6 Fehlmuster mit dem korrekten Muster aus. Ich glaube nicht, das
es da in NET einen besseren/ anderen Ansatz gibt. Dummerweise hindert
mich dieses Vorgehen an der Nutzung der JET für die CSV.

zu Problem2: Mein jetziges Vorgehen in VB6 - Ich zerlege das Datum und
setze es mit dateserial wieder zusammen.

zu Problem3: Jeder CSV Datensatz enthàlt eine eindeutige ID im Format
integer. Diese ID habe ich in der MDB indiziert ohne Duplikate. Ich
erstelle aus jeder CSV Zeile ein INSERT INTO Komando und fange die
Fehler ab. (Treiber DAO 3.6) Das funktioniert zwar ist aber sehr
ineffektiv da ich am Ende des Monats 3000 INSERT auslöse und davon 2700
Fehler erhalte. Leider kann ich nicht sortieren, da die ID's nicht
laufend erhöht werden. Heute kommt ID1,ID5,ID8 und morgen kommt
ID2,ID9,ID10 und übermorgen ID3,ID4,ID6,ID7

zu Problem4: schwer zu erklàren

Felder:
[Channel] [Channel(a)Wert] [Channel(b)Wert] [Channel(c)Wert] [Channel
Top2] [ChannelMiddle4] [ChannelBottom5]

Im Feld [Channel] steht a,b oder c. Anhand des korrospondierenden
Wertefeldes (Werte 0-10) Muß in die drei hinteren Felder bei zutreffen
eine 1 und nichtzutreffen eine 0

Beispiel:
CH|(a)|(b)|(c)|T2 |M4 |B5
a | 0 | 5 | 9 | 0 | 0 | 1
c | 0 | 5 | 9 | 1 | 0 | 0
c | 9 | 5 | 0 | 0 | 0 | 1

Momentan verwende ich eine komplizierte select case Konstruktion die ich
für jede Box (Top, Middle, Bottom) aufrufe also 3x pro CSV Datensatz.
Das macht die Sache nicht unbedingt schnell :-( aber funzt.

Private Function get_Box(ByVal channel As String, _
ByVal ra As String, _
ByVal rb As String, _
ByVal rc As String, _
ByVal rd As String, _
ByVal box As String) As Byte
get_Box = 0
Select Case channel
Case Is = "'A'"
If box = "Bottom" And CByte(ra) <= 4 Then get_Box = 1: Exit
Function
If box = "Middle" And CByte(ra) > 4 And CByte(rphone) < 9 Then
get_Box = 1: Exit Function
If box = "Top" And CByte(ra) >= 9 Then get_Box = 1: Exit Function
Case Is = "'B'"
If box = "Bottom" And CByte(rb) <= 4 Then get_Box = 1: Exit
Function
If box = "Middle" And CByte(rb) > 4 And CByte(rmail) < 9 Then
get_Box = 1: Exit Function
If box = "Top" And CByte(rb) >= 9 Then get_Box = 1: Exit Function
Case Is = "'C'"
If box = "Bottom" And CByte(rc) <= 4 Then get_Box = 1: Exit
Function
If box = "Middle" And CByte(rc) > 4 And CByte(rchat) < 9 Then
get_Box = 1: Exit Function
If box = "Top" And CByte(rc) >= 9 Then get_Box = 1: Exit Function
Case Is = "'D'"
If box = "Bottom" And CByte(rd) <= 4 Then get_Box = 1: Exit
Function
If box = "Middle" And CByte(rd) > 4 And CByte(rrep) < 9 Then
get_Box = 1: Exit Function
If box = "Top" And CByte(rd) >= 9 Then get_Box = 1: Exit Function

End Select

End Function


Ich würde mich freuen, wenn jemand für das ein oder andere o.g. Problem
eine Lösung parat hàtte. Ich weiß, das einzelne Probleme in diese NG OT
sind aber das Gesamtkunstwerk soll in NET + ADO umgesetzt werden.

Liebe Grüße,
Thomas
 

Lesen sie die antworten

#1 Stefan Falz [MVP]
22/02/2008 - 21:55 | Warnen spam
Hallo Thomas,

"Thomas Hübner" schrieb

Problem1: Das CSV File ist korrupt (sporadisch tauchen CRLF auf)



würde ich so machen wie Du auch. Aber ich würde die CSV einfach neu
speichern, damit ich sie dann doch mit Jet einlesen kann. Das dürfte
in vielen Fàllen immer noch um einiges schneller sein als jeden DS
dann einzeln zu importieren.

Problem2: Jeder Datensatz enthàlt ein Datum im Ami Format MM/DD/YYYY



Mit einer schema.ini Datei sollte sich das lösen lassen.

http://msdn2.microsoft.com/en-us/library/ms709353(VS.85).aspx

Problem3: Das CSV File enthàlt zum Großteil Datensàtze, die in der DB schon vorhanden sind und ignoriert werden müssen.



INSERT INTO <AccessTabelle>
SELECT ...
FROM import.csv IN "X:\ordner\" "TEXT;"
WHERE <IdSpalte> NOT IN ( SELECT <IdSpalte> FROM <AccessTabelle> )

Ausführen musst Du das mit OleDbCommand. Ungetestet, weil schnell mal
hingeschrieben isses natürlich auch :)

zu Problem4: schwer zu erklàren

Felder:
[Channel] [Channel(a)Wert] [Channel(b)Wert] [Channel(c)Wert] [Channel Top2] [ChannelMiddle4] [ChannelBottom5]

Im Feld [Channel] steht a,b oder c. Anhand des korrospondierenden Wertefeldes (Werte 0-10) Muß in die drei hinteren Felder bei
zutreffen eine 1 und nichtzutreffen eine 0



Hab ich ehrlich gesagt nicht verstanden. Auch nicht mit dem Beispiel,
das wiederum liegt aber mehr daran, dass Du Variablen verwendest,
die weder übergeben noch innerhalb der Methode deklariert werden und
man somit gar nicht weiß, was man mit denen machen soll. Da sie nicht
aus der CSV Datei kommen, wirds eh schwer. Wenn Sie in einer Access-
Datenbank stehen, könnte man da evtl. was konstruieren aber wie genau
kann ich dir nicht sagen.

Ich weiß, das einzelne Probleme in diese NG OT sind



Warum sollten einzelnen Probleme hier OT sein?

Tschau, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

Ähnliche fragen