Laden...

CSV bearbeiten

Erstellt von Jemall vor einem Jahr Letzter Beitrag vor einem Jahr 515 Views
J
Jemall Themenstarter:in
11 Beiträge seit 2022
vor einem Jahr
CSV bearbeiten

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");
             }

T
2.219 Beiträge seit 2008
vor einem Jahr

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.

J
Jemall Themenstarter:in
11 Beiträge seit 2022
vor einem Jahr

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 🙂

16.807 Beiträge seit 2008
vor einem Jahr

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

J
Jemall Themenstarter:in
11 Beiträge seit 2022
vor einem Jahr

Danke dass combine() werde ich anwenden,
der csvhelper fand ich irgnedwie kompliziert... oder ich bin einfach noch zu sehr anfänger

16.807 Beiträge seit 2008
vor einem Jahr

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 😉

T
2.219 Beiträge seit 2008
vor einem Jahr

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.

J
Jemall Themenstarter:in
11 Beiträge seit 2022
vor einem Jahr

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.

T
111 Beiträge seit 2005
vor einem Jahr

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

J
Jemall Themenstarter:in
11 Beiträge seit 2022
vor einem Jahr

Danke für die Nachricht thomas.at

leider mag er sb.ToString() nicht. Hat den falschen Typ (CS1503)

T
2.219 Beiträge seit 2008
vor einem Jahr

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.

C
2.121 Beiträge seit 2010
vor einem Jahr

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 🙂