2017-06-14 102 views
-2

我會解釋我需要什麼。如何使用C#從csv文件中刪除不必要的空白並對數據網格進行排序?

在程序結束時,將能夠輸入csv文件,計算並輸出結果。現在我正在一步一步做。

  1. 能夠導入CSV到datagridview的(做)
  2. 刪除不必要的空格,排序它的名字(在建)
  3. 計算

爲了使我的問題清晰和易於理解,這裏是csv文件示例。

enter image description here

正如你可以看到有反覆「lotID」是每一個部分,和2類型lotID。

這就是我迄今爲止所做的。讓我們稱這張照片爲a.I,我成功過濾掉了第一個lotID的lotID。

enter image description here

這是PIC B,你可以看到所述第二類型的 'LotID'(MSA)是在每個部分

enter image description here

再次顯示爲可在PIC甲看到,每個部分的lotID不重複,每個部分出現空白。這是我嘗試要解決的第一件事。其次,我想過濾掉第二個類型lotid的'LotID'標題。

這是代碼。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace test2 
{ 
    public partial class Form1 : Form 
    { 
     OpenFileDialog openFile = new OpenFileDialog(); 

     public Form1() 
     { 
      InitializeComponent(); 
     } 


     private void Button1_Click(object sender, EventArgs e) 
     { 
      if (openFile.ShowDialog() == DialogResult.OK) 
      { 
       List<string[]> rows = File.ReadLines(openFile.FileName).Select(x => x.Split(',')).ToList(); 
       DataTable dt = new DataTable(); 
       List<string> headerNames = rows[0].ToList(); 
       foreach (var headers in rows[0]) 
       { 
        dt.Columns.Add(headers); 
       } 
       foreach (var x in rows.Skip(1)) 
       { 
        if (x.SequenceEqual(headerNames)) //linq to check if 2 lists are have the same elements (perfect for strings) 
         continue;  //skip the row with repeated headers 
        dt.Rows.Add(x); 
       } 

       dataGridView1.DataSource = dt; 
      } 
     } 

     private void Form1_Load_1(object sender, EventArgs e) 
     { 
      openFile.Filter = "CSV|*.csv"; 
     } 
    } 
} 
+0

給我一秒鐘,我只是閱讀你發佈的數據。 – CodingYoshi

+0

你想要空白區域和標題不顯示Datagridview? –

+0

@CodingYoshi慢慢來!謝謝! – ccs

回答

1

對於由報頭&去除空行排序,嘗試這段代碼:(這需要你知道「批次標識」將是第一個塔)

private void Button1_Click(object sender, EventArgs e) 
{ 
    if (openFile.ShowDialog() == DialogResult.OK) 
    { 
     List<string[]> rows = File.ReadLines(openFile.FileName).Select(x => x.Split(',')).ToList(); 
     DataTable dt = new DataTable(); 
     List<string> headerNames = rows[0].ToList(); 
     foreach (var headers in rows[0]) 
     { 
      dt.Columns.Add(headers); 
     } 
     foreach (var x in rows.Skip(1).OrderBy(r => r.First())) //sort based on first column of each row 
     { 
      if (x.SequenceEqual(headerNames)) //linq to check if 2 lists are have the same elements (perfect for strings) 
       continue;  //skip the row with repeated headers 
      if (x.All(val => string.IsNullOrWhiteSpace(val))) //if all columns of the row are whitespace/empty, skip this row 
       continue; 
      dt.Rows.Add(x); 
     } 

     dataGridView1.DataSource = dt; 
    } 
} 

作爲一種hackish的方法,以消除重複的一個標題行,你可以試試這個:

if (x[0] == "Lot ID") 
    continue; 

,而不是

if (x.SequenceEqual(headerNames)) 
    continue; 

這不是很優雅,但它會工作。

我會添加一些說明所使用的LINQ方法:

File.ReadLines(openFile.FileName).Select(x => x.Split(',')).ToList(); 

讀取文件中的所有行的。選擇經過各條線和分割基於commma(因爲它是CSV)。默認情況下,分割返回一個分割值的數組,最後ToList()表示這一行返回一個字符串數組的List。數組包含單個單元格值,而列表包含行。

List<string> headerNames = rows[0].ToList(); 

這保存了第一行,其中包含所有標題名稱到一個單獨的列表中,我們稍後可以使用它。

foreach (var x in rows.Skip(1).OrderBy(r => r.First())) 

跳過()方法忽略了列表中的第一個元素(並且採取所有其他),以及排序依據()按字母順序排序中,r => r.First()只是用於每一行的「r」,根據「r.First()」中的第一列進行排序。 「x」代表每一行。

if (x[0] == "Lot ID") 

這不是LINQ了,它只是檢查是否此行的第一列是「批次標識」,如果是「繼續」跳到中的foreach下一行。

希望我的解釋能幫助你學習!鏈接到一些基本的LINQ在評論中。

+0

您是否有任何想法去除PIC B中顯示的lotID? – ccs

+0

你的意思是重複標題行,或重複行下的值?如果你的意思是重複的頭文件,那麼'if(x.SequenceEqual(headerNames))'不能正確地修復? –

+0

它確實爲HJ64615F的LotID修復,但是MSA – ccs

相關問題