Hi,
ich hoffe ich bin im richtigen Unterforum.
Ich bearbeite jetzt schon eine beachtliche Zeit meinen Code aber bekomme meinen letzten Fehler nicht bereinigt...
Ich habe eine CSV mit 19 Spalten und x Zeilen. Ich möchte in Abhängigkeit von Spalte 11 und 13 (je nach Inhalt) einen String als Spalte 20 hinzuhängen.
Es klappt soweit auch alles gut, außer wenn der Inhalt von "Spalte 11" 3-Zeichen lang (also > 99) ist. Dann ist die komplette Zeile leer!
Ich habe ja irgendwie mein "length" in Verdacht. Aber nur eine Vermutung 😉.
//Zeilen einlesen
string[] zeilen = File.ReadAllLines(textBoxPfad.Text + textBoxDatei.Text);
// alle Zeilen abarbeiten
for (x1 = 0; x1 < zeilenanzahl; x1++) //x1 = Zeilen
{
//Zeilen auftrennen in Spalten (Seperator ;)
string[] Spalten = zeilen[x1].Split(';');
y1 = 1;
y2 = 1;
//Header bei Zeile 0 einsetzen
if (x1 == 0) { zeilen2[0] = zeilen[0].Insert(laenge, ""); }
else
{
//ab Zeile 1 Je nach Spalte 11 und 13 anhängen
laenge = zeilen[x1].Length;
if (Spalten[13].Contains("30"))
{
for (y1 = 1; y1 <= 160; y1++) //Anzahl der Fehler Bezeichnungen
{
// Bei Spalte 13 = 30 und Spalte 11 einen bestimmten Wert zwischen 1 - 161 (name10 wurde einen bestimmten String zugewisen)
if (int.Parse(Spalten[11]) == y1) { zeilen2[x1] = zeilen[x1].Insert(laenge, name10[y1 - 1]); }
if (y1 >= 161){ break; }
}
}
else
{
//Spalte 13 = 10: gleiches nur andere Begriffe als String
if (Spalten[13].Contains("10"))
{
for (y2 = 1; y2 <= 43; y2++) //Anzahl der Warnungs Bezeichnungen
{
if (int.Parse(Spalten[11]) == y2) { zeilen2[x1] = zeilen[x1].Insert(laenge, name30[y2 - 1]); }
if (y2 >= 44) { break; }
}
}
else
{
zeilen2[x1] = zeilen[x1];
MessageBox.Show("Fehlerhafter Wert bei Priority"+" Zeile "+(x1+1));
}
}
}
}
//Klartext anhaengen
File.WriteAllLines(textBoxPfad.Text + textBoxDatei.Text, zeilen2);
MessageBox.Show("Klartexte wurden der CSV hinzugefuegt");
}
Wenn in den Spalten nur Zahlenwerte stehen können, dann kannst du auch einfach den Inhalt per Int32.TryParse versuchen umzuwandeln.
Dabei sollte aber geprüft werden ob der Content nicht leer ist, sonst knallt es bei TryParse.
Dann musst du auch nicht auf 2 oder 3 Stellen prüfen 😉
Anbei wäre es auch besser, denn du deinen Code sauberer aufteilst.
Aktuell scheint die gesamte Verarbeitung in einer Methode zu sein, was das lesen des Code unnötig schwer macht.
Das auslesen, verarbeiten und schreiben sollte in eigene Methoden ausgelagert werden.
Im einfachsten Fall lagerst du diese in eine Klasse aus, die sich dann darum kümmert.
Dann kannst du den Code auch später z.B. mit Tests (Unittests) abdecken.
T-Virus
Developer, Developer, Developer, Developer....
99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
Ich prüfe ja nicht auf 2,3 Stellen, sondern lasse einfach nur eine For Schleife durchlaufen die schaut ob es mit dem Wert über einstimmt.
Ja zu der Lesbarkeit, aber ich bin eher in der SPS Programmierung und eigne mir gerade C# an... was man sieht 🙂
Eine CSV funktioniert nicht zwangsläufig in Spalten.
Nutz besser eine geeignete Library dafür, zB GitHub - JoshClose/CsvHelper: Library to help reading and writing CSV files
PS: bitte keine Pfade von Hand zusammenpuzzlen.
https://docs.microsoft.com/en-us/dotnet/api/system.io.path.combine?view=net-6.0
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Danke dass combine() werde ich anwenden,
der csvhelper fand ich irgnedwie kompliziert... oder ich bin einfach noch zu sehr anfänger
Aber die Beispiele hast gesehen?
Getting Started | CsvHelper
Brauchst ja nur eine Klasse, die eine Zeile repräsentiert - und der Rest macht die Lib für Dich.
Aktuell erfindest Du das Rad neu, aber eckig 😉
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Okay, aber einiges im Code macht keinen Sinn.
Die Prüfungen mit Contains, kannst du bei vorheriger Konvertierung einfach über eine Werte Prüfung lösen.
Ebenfalls scheinst du auch in den Schleifen mehrfach unnötig TryPase aufzurufen.
Je nachdem wieviele Zeilen du hast, verheizt du dadurch unnötig Zeit um die immer gleichen Spalten zu konvertieren.
Es wäre vermutlich auch hilfreicher, wenn du einmalig die Zeile aus den zeilen Array ausliest und zwischen speicherst.
Aktuell musst du immer wieder über zeilen[x1] darauf zugreifen, was du auch mit einer string Variable vereinfachen kannst.
Auch ist mir nicht ganz klar war zeilen2 ist bzw. woher es kommt.
Mit den if Abfragen mit dem break der inneren Schleife hast du auch einie magic numbers.
Mach daraus am besten Konstanten damit später klar ist, warum du darauf prüfst und rausspringen musst.
Die Meldungen mit fehlerhaften Zeilen würde ich einmal sammeln und dann insgesamt ausgeben.
Sonst musst du für jede fehlerhafte Zeile dem Benutzer ein Fenster anzeigen.
Das macht bei vielen fehlerhaften Zeilen keinen Spaß!
T-Virus
Developer, Developer, Developer, Developer....
99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
Brauchst ja nur eine Klasse, die eine Zeile repräsentiert - und der Rest macht die Lib für Dich.
Aktuell erfindest Du das Rad neu, aber eckig 😉
Also wenn ich es jetzt so wie ich es habe nicht hinbekomme, ja dann werde ich es nochmal versuchen.
zeile2 ist die gesamte .csv mit angehängter Spalte die dann reingeschrieben wird zum Schluss.
Das Ausbessern von unschönen Formfehler/Anfängerfehler nehme ich auch dankend an.
Aber es hilft mir gerade noch nicht bei der Lösung und die hat für mich Vorrang.
Wenn ich den o.g. Fehler gefunden habe dann werde ich definitiv an das Umsetzen eurer Vorschläge gehen.
Hallo
Ich würde das mit einem StingBuilder und zwei geschaltelten Schleifen machen:
StringBuilder sb = new StringBuilder();
int spalte11;
string spaltezusatz = string.Empty;
string[] zeilen = File.ReadAllLines(Textdatei);
sb.AppendLine(zeilen[0] + ";Zusatzspalte"); //Headerzeile
for (int zeile = 1; zeile < zeilen.Length; zeile++) //alle Zeilen ab 2. Zeile
{
spaltezusatz = string.Empty;
string[] Spalten = zeilen[zeile].Split(';'); // Zeile zerlegen
for (int spalte = 0; spalte < Spalten.Length; spalte++) // alle Spalten durchlaufen
{
if (spalte == 13) // Spalte 13
{
if (Spalten[spalte] == "30") // Wert
{
if (Int32.TryParse(Spalten[11], out spalte11) && spalte11 <= 160) // Wert aus Spalte 11 umwandeln und auf <= 160 prüfen
spaltezusatz = name10[spalte11]; // Wert aus name10 in "Zusatzspalte"
}
else
{
if (Spalten[spalte] == "10")
{
if (Int32.TryParse(Spalten[11], out spalte11) && spalte11 <= 43) // w.o.
spaltezusatz = name30[spalte11];
}
else
{
MessageBox.Show("Fehler");
}
}
}
sb.Append(Spalten[spalte] + ";");
}
if (!string.IsNullOrWhiteSpace(spaltezusatz )) // zusatzspalte gesetzt
sb.AppendLine(spaltezusatz ); // zur Zeile hinzufügen
else
sb.AppenLine("");
}
File.WriteAllLines(Pfad, sb.ToString()); // Zeilen schreiben
LG
Thomas
Danke für die Nachricht thomas.at
leider mag er sb.ToString() nicht. Hat den falschen Typ (CS1503)
Liegt daran, dass bei WriteAllLines ein String Array erwartet wird.
Hier muss eher WriteAllText verwendet werden.
T-Virus
Developer, Developer, Developer, Developer....
99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
Mit den if Abfragen mit dem break der inneren Schleife hast du auch einie magic numbers.
Noch schlimmer. Wenn man die for Schleife bis y2 ≤ 43 laufen lässt, muss man nicht mehr aus ihr herausspringen wenn y2 ≥ 44 ist 🙂