none
Textdatei lesen, in eine DataTable, bearbeitete Zeilen zu Beginn mit einer Markierung versehen

    Frage

  • Hallo,
    ich fragte vor ein paar Wochen schon mal was ähnliches an.
    Dabei bin ich weitergekommen und nehme jetzt ein Dataset.
    Somit kann ich auf Zeile, Spalte zugreifen.
    Der Code sieht wie folgt aus.
    public DataTable GetDataSourceFromFile(string fileName)
    {
     DataTable dt = new DataTable("ProductData");
     string[] columns = null;
     var lines = File.ReadAllLines(fileName);
     // the first row contains the columns information
     if (lines.Count() > 0)
     {
      columns = lines[0].Split(new char[] { '|' });
      int number = 0;
      foreach (var column in columns)
      {
         dt.Columns.Add(column);
           number++;
      }
     }
     // reading rest of the data
     for (int i = 1; i < lines.Count(); i++)  // oder besser lines.Count   ????
     {
      DataRow dr = dt.NewRow();
      string[] values = lines[i].Split(new char[] { '|' });
      for (int j = 0; j < values.Count() && j < columns.Count(); j++)
       dr[j] = values[j];
      dt.Rows.Add(dr);
     }
     string abc = dt.Rows[0]["NummerEinkauf"].ToString();
     abc = dt.Rows[7]["NummerEinkauf"].ToString();
     var filePaths = dt.AsEnumerable()
    .Select(row => row.Field<string>("NummerEinkauf"))
    .ToArray();
    
    // diese Abfrage geht nicht.
     var filePaths2 = dt.AsEnumerable()
    .Select(row => row.Table.Columns.Contains("NummerEinkauf") && !row["NummerEinkauf"].ToString().StartsWith("#"))
    .Take(5);
     return dt;
    }
    publiv void SchreibeDaten()
    {
       //Die entnommene n Anzahl müssen das Bearbeitungszeichen # bekommen.
    }

    Probleme sind jetzt.
    Ich muss jetzt die nächsten n Zeilen bearbeiten, die nicht mit # beginnen.
    Anschließend in ein Textfile speichern.
    Wie erzeuge ich korrekt die LinQ Abfrage?
        Nehme die erste Spalte, gehe zur ersten Zeile die nicht mit # beginnt,
     hole da n Zeilen heraus.
    Wie schreibe ich von einer Datatable, das File, mit den Trennungszeichen '|'?

    Es sind aus der Gesamtliste z.B. 5, 10 oder 13 Zeilen aktiv.
    string GetInhalt(int Zeilennummer, string Spaltenname)


    Das wäre es.
    NummerEinkauf|NummerVerkauf|Intern|Country|Count|Date|Type
    #200495068|014074785-027|4002045401|D|7LP|20.02.2017|IFC 050 24VDC CPU
    #200495069|014074785-028|4002045401|D|7LP|20.02.2017|IFC 050 24VDC CPU
    #200495070|014074785-029|4002045401|D|7LP|20.02.2017|IFC 050 24VDC CPU
    #200495071|014074785-030|4002045401|D|7LP|20.02.2017|IFC 050 24VDC CPU
    200495072|014074785-031|4002045401|D|7LP|20.02.2017|IFC 050 24VDC CPU
    200495073|014074785-032|4002045401|D|7LP|20.02.2017|IFC 050 24VDC CPU
    200495074|014074785-033|4002045401|D|7LP|20.02.2017|IFC 050 24VDC CPU
    200495075|014074785-034|4002045401|D|7LP|20.02.2017|IFC 050 24VDC CPU
    200495076|014074785-035|4002045401|D|7LP|20.02.2017|IFC 050 24VDC CPU
    200495077|014074785-036|4002045401|D|7LP|20.02.2017|IFC 050 24VDC CPU
    200495078|014074785-037|4002045401|D|7LP|20.02.2017|IFC 050 24VDC CPU
    200495079|014074785-038|4002045401|D|7LP|20.02.2017|IFC 050 24VDC CPU
    200495080|014074785-039|4002045401|D|7LP|20.02.2017|IFC 050 24VDC CPU
    200495081|014074785-040|4002045401|D|7LP|20.02.2017|IFC 050 24VDC CPU

    Viele Grüße Markus

    Donnerstag, 12. Oktober 2017 16:58

Antworten

  • Hallo Markus,

    ich würde etwas anders an die Sache herangehen. Zuerst - sofern die Spalten von der Position her variabel sind - würde ich den relevanten Index heraussuchen und danach die Liste der gültigen Zeilen erstellen:

    // Index (Spalte) in der Textdatei heraussuchen
    var IndNrEinkauf = columns.IndexOf("NummerEinkauf");
    
    // DataTable & Rows erzeugen ...
    
    // Linq-Abfrage
    var validDR = (from DataRow row in dt.Rows select row).Where(r=>!((string)r.ItemArray[IndNrEinkauf]).StartsWith("#")).ToList();
    
    
    

    Zum Schreiben gehst Du dann nur das Array mit den gültigen Zeilen durch, erzeugst je Zeile den String und schreibst das Ergebnis in einen Stream. Müsste ungefähr so aussehen:

      // alle gültigen Einträge durchlaufen
      foreach(var row in validDR)
      {
        // String einer Zeile erstellen
        var szLine = string.Empty;
        for(int i = 0; i < columns.Count; ++i)
        {
          // Trennsymbol
          if(i>0)
            szLine = szLine + "|";
        
          // Inhalt
          szLine = szLine + (string)row.ItemArray[i];
        }
    
        // jetzt szLine in den Stream schreiben
      }    

    Viele Grüße

    Christoph

    Donnerstag, 12. Oktober 2017 19:25
  • Hallo Markus,

    für das folgende Beispiel ist diese Library im Einsatz: LINQtoCSV
    DOKU: https://www.codeproject.com/Articles/25133/LINQ-to-CSV-library

    Das ist ein NugetPaket: bitte LINQtoCSV.Excel  in dein Projekt einbinden.

    Das Beispiel geht davon aus das deine Testdaten unter C:\temp\inputdatei.csv liegen.
    Das Resultat soll am Ende in C:\temp\outputdatei.csv stehen.

    Das ist folgendes Using was hinzukommt
    using LINQtoCSV;

    Danach soll folgender Code das erledigen wenn ich das richtig verstanden habe:

                // Quelltextdatei unter C:\temp\testdatei.csv
                string inputdatei = "C:\\temp\\inputdatei.csv";
                string outputdatei= "C:\\temp\\outputdatei.csv";
                CsvFileDescription inputFileDescription = new CsvFileDescription
                {
                    SeparatorChar = '|',
                    FirstLineHasColumnNames = true
                };
                CsvContext cc = new CsvContext();
                IEnumerable<Testdaten> testdaten=    cc.Read<Testdaten>(inputdatei, inputFileDescription).Where( p => p.NummerEinkauf.StartsWith("#")).ToList();
        
                CsvFileDescription outputFileDescription = new CsvFileDescription
                {
                    SeparatorChar = '|', // tab delimited
                    FirstLineHasColumnNames = true // no column names in first record
                };
                cc.Write(    testdaten,    outputdatei,    outputFileDescription);

    Nötig ist noch der Typ, hier Testdaten ein POCO welche so ausschaut:

        public class Testdaten
        {
            //NummerEinkauf|NummerVerkauf|Intern|Country|Count|Date|Type
            //#200495068|014074785-027|4002045401|D|7LP|20.02.2017|IFC 050 24VDC CPU
            public Testdaten()
            { }
            public string NummerEinkauf { get; set; }
            public string NummerVerkauf { get; set; }
            public string Intern { get; set; }
            public string Country { get; set; }
            public string Count { get; set; }
            public string Date { get; set; }
            public string Type { get; set; }
        }

    Die Doku vom Autor ist aus meiner Sicht mehr als Ok, und Du kommst so hoffe ich damit zurecht.

    HTH

    Grüße Alexander

     

    Freitag, 13. Oktober 2017 20:55

Alle Antworten

  • Hallo Markus,

    ich würde etwas anders an die Sache herangehen. Zuerst - sofern die Spalten von der Position her variabel sind - würde ich den relevanten Index heraussuchen und danach die Liste der gültigen Zeilen erstellen:

    // Index (Spalte) in der Textdatei heraussuchen
    var IndNrEinkauf = columns.IndexOf("NummerEinkauf");
    
    // DataTable & Rows erzeugen ...
    
    // Linq-Abfrage
    var validDR = (from DataRow row in dt.Rows select row).Where(r=>!((string)r.ItemArray[IndNrEinkauf]).StartsWith("#")).ToList();
    
    
    

    Zum Schreiben gehst Du dann nur das Array mit den gültigen Zeilen durch, erzeugst je Zeile den String und schreibst das Ergebnis in einen Stream. Müsste ungefähr so aussehen:

      // alle gültigen Einträge durchlaufen
      foreach(var row in validDR)
      {
        // String einer Zeile erstellen
        var szLine = string.Empty;
        for(int i = 0; i < columns.Count; ++i)
        {
          // Trennsymbol
          if(i>0)
            szLine = szLine + "|";
        
          // Inhalt
          szLine = szLine + (string)row.ItemArray[i];
        }
    
        // jetzt szLine in den Stream schreiben
      }    

    Viele Grüße

    Christoph

    Donnerstag, 12. Oktober 2017 19:25
  • Hallo Markus,

    für das folgende Beispiel ist diese Library im Einsatz: LINQtoCSV
    DOKU: https://www.codeproject.com/Articles/25133/LINQ-to-CSV-library

    Das ist ein NugetPaket: bitte LINQtoCSV.Excel  in dein Projekt einbinden.

    Das Beispiel geht davon aus das deine Testdaten unter C:\temp\inputdatei.csv liegen.
    Das Resultat soll am Ende in C:\temp\outputdatei.csv stehen.

    Das ist folgendes Using was hinzukommt
    using LINQtoCSV;

    Danach soll folgender Code das erledigen wenn ich das richtig verstanden habe:

                // Quelltextdatei unter C:\temp\testdatei.csv
                string inputdatei = "C:\\temp\\inputdatei.csv";
                string outputdatei= "C:\\temp\\outputdatei.csv";
                CsvFileDescription inputFileDescription = new CsvFileDescription
                {
                    SeparatorChar = '|',
                    FirstLineHasColumnNames = true
                };
                CsvContext cc = new CsvContext();
                IEnumerable<Testdaten> testdaten=    cc.Read<Testdaten>(inputdatei, inputFileDescription).Where( p => p.NummerEinkauf.StartsWith("#")).ToList();
        
                CsvFileDescription outputFileDescription = new CsvFileDescription
                {
                    SeparatorChar = '|', // tab delimited
                    FirstLineHasColumnNames = true // no column names in first record
                };
                cc.Write(    testdaten,    outputdatei,    outputFileDescription);

    Nötig ist noch der Typ, hier Testdaten ein POCO welche so ausschaut:

        public class Testdaten
        {
            //NummerEinkauf|NummerVerkauf|Intern|Country|Count|Date|Type
            //#200495068|014074785-027|4002045401|D|7LP|20.02.2017|IFC 050 24VDC CPU
            public Testdaten()
            { }
            public string NummerEinkauf { get; set; }
            public string NummerVerkauf { get; set; }
            public string Intern { get; set; }
            public string Country { get; set; }
            public string Count { get; set; }
            public string Date { get; set; }
            public string Type { get; set; }
        }

    Die Doku vom Autor ist aus meiner Sicht mehr als Ok, und Du kommst so hoffe ich damit zurecht.

    HTH

    Grüße Alexander

     

    Freitag, 13. Oktober 2017 20:55