C# Telekom Rechnung als CSV mit C# auslesen

I N X S

Captain
Registriert
Jan. 2007
Beiträge
3.446
Huhu,

ich will ein keines Programm schreiben, dass mir eine Telekomrechnung ausliest und die daten so umwandelt, dass ich sie in eine datenbank shcreiben kann.

die umwandlung bzw. überprüfung der werte ist durch reguläre ausdrücke kein problem.

schwieriger wirds eher, da die werte mit , getrennt sind und jeweils noch mit " eingefasst. das problem ist, dass mehrfach werte mit komma vorkommen,deshalb geht ein split nicht.

Ein weiteres problem ist, dass die datei als "Überschrift" 3 zeilen mit infos hat und dann eine leerzeile. dann beginnt erst der "tabellenteil"

sieht ungefähr so aus:
Code:
"Rechnung Online - Rechnungspositionen"
"Buchungskonto xxxxxxxxxxxx"
"Rechnungsnummer xxxxxxxxxxxx vom 29.07.2010"

"Rechnungsbereich","Produktfamilie","Anbieter","Vertragsnummer","Billing Account Gruppe","Anschlussart","Anschluss","Info zur Anschlussart","Info zum Anschluss","Anzahl Verbindungen","Die Leistungen im Einzelnen","Art.-/Leist.-Nr.","Menge/Volumen/tarifierte Zeit","Nettoeinzelbetrag (Euro)","Nettogesamtbetrag (Euro)","USt.(%)"
"Sondertarife","---","Deutsche Telekom AG","xxxxxx","xxxxx","BAG-Vertrag","xxxxx","---","---","---","---","","---","---","-12,13","19"
"Monatliche Beträge vom 01.08.10 bis 31.08.10","Sonstige Beträge","Deutsche Telekom AG","---","---","Rufnummer","xxxxxx","---","---","---","Rechnung Online Komfortversion","xxxxx","---","11,0200","11,02","19"


da kommen dann noch mehrere einträge und ich hab die sensibelen daten mal mit xxxxx unkenntlich gemacht.

ich hoffe ihr könnt mir helfen, denn "a fast csv reader" und "filehelper" sind nicht sehr nützlich bei der formatierung.

ich könnte das ganze natürlich auch per hand schreiben, aber würde mich freuen wenn jemand erstmal nen vorschlag hätte ;)
 
Ich weiß nicht wo dein Problem ist ? Ist doch super, dass alles nach komma getrennt ist. Da gibt es im .net framework diverse Funktionen für die Stringverarbeitung (substring, instr etc...). Guck dir die mal an. Die Anführungszeichen kannste ganz einfach mit ".replace("""","")" entfernen.

Du gehst also wie folgt vor. Speicher dir "," als Trennzeichen in eine variable und dann verarbeitst du das ganze mit "instr". Wie du das verwurschtelst musste schon selber gucken..
 
einfach nur das zwisschen den "" auslesen? :) ist ja immer nen öffnendes und schließendes " die Kommas kannst ja nachdem InfoHeader erst berücksichtigen... ist aber eigentlich nicht nötig falls die Telekom Rechnung immer richtig formatiert ist.
 
jo das zwischen den " " auslesen kann ich ja von hand machen, das ist kein problem.


sevenup, das problem ist dass replace oder split nicht weiss, welches komma in einer zahl steckt und welches ein trennzeichen ist...
 
sorry, hatte übersehen das Daten ebenfalls verarbeitet werden müssen...

Wenn du weißt in welchen Zeilen die einzelnen Einträgen sind und weißt in welchen Zeilen kommas außerhalb der Trennung vorkommen, könntest du die Zeilen einzeln durchgehen, schön geht aber auch anders...
Ergänzung ()

Neue Idee... nimm einfach ", als Trennzeichen anstatt nur , ... somit umgehst du jedenfalls, dass er auch bei einem Datum nach dem Komma trennen würde
 
Net ist nicht meine Welt...
ist es nicht möglich die " durchzunummerieren? mit ihrer Stelle im String?
dann sind das 0te 2te 4te " öffnende und alle ungeraden schließende...
dann von 0ten zum 1ten auslesen 2tem zum 3ten.... die Kommas sind dann egal

kann in Net doch nicht so schwer sein :) sind ja nurn paar zeilen c code ;)

mal nachgeschaut z.B mit [string].IndexOf('"') kriegste die Position nun den string nach dem " abschmneiden, nochmals suchen nach " nun nen substring von 0 bis zum nächsten ", string abschneiden und so weiter.... sieht für mich ohne Net Kenntnissse am einfachsten aus ;)

gruß
 
Zuletzt bearbeitet:
@soyd: Durchnummerierung, ich bitte dich, was sind das denn für Spezialbehandlungen?!:rolleyes:

Als erstes würde ich mal suchen ob es schon implementierungen für CSV Reader gibt die man eventuell für sich benutzen kann.
http://www.codeproject.com/KB/database/CsvReader.aspx
Dann würde ich tatsächlich einen anderen Delimeter wählen.
Die Logik das man die Values in " " ist ganz gut, weil man so eben keine Sonderbehandlung für Dezimalzahlen braucht.
Ich würde einfach den ; als delimeter nehmen, und sobald dieser in einer Value auftauchen sollte würde ich den einfach ignorieren.
 
Ja das ist ne Gute Idee, die Frage ist hier, ob die Performance darunter leidet oder nicht.
Man müsste beide Varianten mal ausprobieren, wobei ich schon fast sagen würde die Regex-Variante zieht die Performance runter.
 
Huhu,

Das Problem ist, dass die Rechnung die ich da bekommen hatte schrott war.

die richtigen rechnungen haben nen ; als seperator, aber nicht immer " ". da könnte man halt wirklich mit split arbeiten, ich muss mich erstmal durch die datenmassen wühlen um zu schauen ob das überall gleich ist.

Das sind im Monat ca. 8-10MB nur an csv datein, is zwar happig, aber performance ist da nicht so wichtig, da die daten nur einmalig einghespielt werden müssen.


erstmal muss ich mein datenbankmodell fertig kriegen und schauen ob ich das monaten gliedere oder lieber nach rechnungsnummern, ich tendiere zu letzerem ^^
 
Naja 8-10MB sind jetzt nich wirklich happig. Die sind schnell eingelesen und verarbeitet. Ok, wenn die Daten natürlich in einer inkositenten Art und Weiße vorliegen, machts die Sache natürlich schon unangenehmer.
 
wies ausschaut ist ; der richtige trenner. keine ahnung warum man mir eine beispielrechnung mit , gegeben hat oO

jede datei hat nen header, ne leerzeile und dann ist die aufteilung einheitlich.


wieviel datensätze kann man dann in ner MS SQL datenbank unterbringen bevor die geschwindigkeit leidet?
 
Also Geschwindigkeit ist weniger Abhängig von Menge als von Aufbau. Also so ne Datenbank kannste ohne Probleme mit 4GB füllen eh du da überhaupt was merkst.Kommt ja auch drauf an ob du deine Werte indizierst und ob die Abfragen optimiert sind bzw. ob Views vorliegen. Ach da gibts viele Faktoren. Aber da würde ich mir erst Sorgen machen wenn du wirklich Geschwindigkeitsprobleme bekommst ;)
 
Wir haben hier MS SQL 2005 Datenbanken mit 6-13 GB Größe und mehreren Millionen Einträgen und das ist immer noch relativ schnell.
Da kannst du also schon ein paar Jahre Rechnungen reinbrettern.
 
Ah ok dann dank ich euch ;)

Dann werde ich 4 haupttabellen machen und keine einteilung in monate, sondern halt jeweils nur das rechnungsdatum auslesen. die sortiersache kommt ja später.

ich habs jetzt so:
jede firma hat mehrere rechnungen und jede rechnung hat mehrere Einzelverbindungsnachweise.

parallel hat jede firma mehrere anschlüsse, die wiederrum jeweils mehrere EVNs haben.

Rechnung und Anschluss verweisen dementsprechend auf die firmen_ID und evn auf rechnungs und anschluss ID.


Ohje da werd ich die nächsten monate spass mit haben <.<
 
Ach komm, die Datenbank dafür ist doch das kleinste Problem...zumindest wie es sich für mich bis jetzt anhört...
 
Ja für so alte hasen wie euch ;) Ne also das DB Design krieg ich demnächst fertig, das ist wirklich nicht das problem.

eher grauts mir davor, dass ich programmieren muss, dass die daten für jeden monat automatisch eingelesen werden müssen ohne duplikate usw. die verweise und alles müssen funktionieren und fehlende angelegt werden. und dann muss ich ein interface machen, mit dem man das ganze analysieren kann mit statistik filtern usw.

Ich bin wie gesagt noch nicht so lange dabei, das tipp ich nicht einfach so runter :D

aber man lernt unglaublich viel dabei, viel mehr als im studium - was schade ist, aber umso besser dass ic hden kob hab ;)
 
Naja was heisst "alte Hasen wie euch", ich bin auch erst 23 hab ne ITA Ausbildung gemacht und bin jetzt im 3. Semester(Studium Angewandte Informatik)^^.
Aber beim solche Dinge wie das einlesen von Daten hasse ich auch immer zu programmieren, wobei es bei csv-Dateien ja noch schnell von statten geht aufgrund der Struktur.

Aber denk dran, bei dem was du machen willst ist das DB Design entscheidend, da du hiermit(Wenn das Design halt passend ist) direkt schon Dingen wie doppelten Einträgen aus dem weg gehen kann, bzw. das DBMS dir einiges an arbeit abnehmen kann.
 
Wenn es ein CSV Datei ist, kannst du ja dann auch die Spalten verarbeiten.

Splitte zuerst die erste Zeile, dann speichere das in einen Array.... Wenn due weißt wie die Spalten heißen sollen die du brauchst, dann.... ach was solls...



Code:
String[] all = Stream.ReadAll(...).Splitt("\r\n"); //oder nur \n

String[] head = String.Splitt("erste Zeile");

Int[] spaltendiedubrauchst = SpaltenDieDuBrauchst(head); ///schreib ne Methode die deine bestimmte spalten extrahiert.

foreach(String inner in all)
{
    String[] innerList = inner.Splitt("deine params");
    for(int i = 0; i < innerList.Count; i++)
    {
        if(spaltendiedubrauchst.Contains(i)
            ....//tu was du hier tun willst... Methodenverweis oder was auch immer
    }
}

Achtung, es ist kein richtiger Code, da ich ehe nur aus dem Autovervollständige die ganzen Methode heraussuche und diese nicht im Kopf habe. Aber so ähnlich kann man es aufbauen.
 
Huhu, die Ausleserei hab ich jetzt schon implementiert.

Gibt es eine möglichkeit in ASP ordner auszuwählen vom jeweils ausführenden computer?
 
Zurück
Oben