Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
CSV bearbeiten
Jemall
myCSharp.de - Member



Dabei seit:
Beiträge: 5

Themenstarter:

CSV bearbeiten

beantworten | zitieren | melden

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");
             }
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Jemall am .
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1.962
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

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
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von T-Virus am .
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.
private Nachricht | Beiträge des Benutzers
Jemall
myCSharp.de - Member



Dabei seit:
Beiträge: 5

Themenstarter:

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15.757

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
Jemall
myCSharp.de - Member



Dabei seit:
Beiträge: 5

Themenstarter:

beantworten | zitieren | melden

Danke dass combine() werde ich anwenden,
der csvhelper fand ich irgnedwie kompliziert... oder ich bin einfach noch zu sehr anfänger
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15.757

beantworten | zitieren | melden

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 ;-)
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1.962
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Jemall
myCSharp.de - Member



Dabei seit:
Beiträge: 5

Themenstarter:

beantworten | zitieren | melden

Zitat von Abt
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.
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von Jemall am .
private Nachricht | Beiträge des Benutzers
thomas.at
myCSharp.de - Member



Dabei seit:
Beiträge: 107
Herkunft: Österreich / Wien

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
Jemall
myCSharp.de - Member



Dabei seit:
Beiträge: 5

Themenstarter:

beantworten | zitieren | melden

Danke für die Nachricht thomas.at

leider mag er sb.ToString() nicht. Hat den falschen Typ (CS1503)
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1.962
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
chilic
myCSharp.de - Experte



Dabei seit:
Beiträge: 2.102

beantworten | zitieren | melden

Zitat
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 :-)
private Nachricht | Beiträge des Benutzers