简体   繁体   中英

c# csv count a specified data in file or in datagridview

I have a csv file and would like to count the 2. column how many times contains 111.

the csv file has 46 separated columns with separator ; .

    "first col"  "second col" "....."
     abc          111           a
     abc          112           b
     abc          113           c
     abc          111           d
     abc          112           e
     abc          113           f

i would like to count the 111. Filled up first the datagridview fom datatable.

        dgv.DataSource = dgv_table;

        string[] raw_text = File.ReadAllLines("d:\\"+lb_csv.Text);
        string[] data_col = null;
        int x = 0;

        foreach (string text_line in raw_text)
        {

            // MessageBox.Show(text_line);
            data_col = text_line.Split(';');

            if (x == 0)
            {
                for (int i = 0; i <= data_col.Count() - 1; i++)
                {

                    dgv_table.Columns.Add(data_col[i]);
                }
                //header

                x++;
            }

            else
            {
                //data

              dgv_table.Rows.Add(data_col);
            }

I find a lots of solution to count the 2nd columns specified data:111 but all time i had problems.

         int xCount = dgv.Rows.Cast<DataGridViewRow>().Select(row => row.Cells["second col"].Value).Where(s => s !=null && Equals(111)).Count();

        this.lb_qty.Text = xCount.ToString();

But it gives error for row.Cells["second col"].Value

 An unhandled exception of type 'System.ArgumentException' occurred in System.Windows.Forms.dll

 Additional information: Column named second col cannot be found.

Can someone help me how to solve this problem and get the needed result?

I would suggest you to skip using DataGridView and use counter variable in your loop, like Arkadiusz suggested.

If you still want to work with DataTable, count values like this:

int xCount = dgv_table.Rows.Cast<DataRow>().Count(r => r["second col"] != null && r["second col"].ToString() == "111");

I would try to read the file into a DataTable and use it as DataSource for the DataGridView .

DataTable d_Table = new DataTable();

//fill the DataTable
this.dgv_table.DataSource = d_Table;

To count the rows wich contains 111 in the second column, you can select the DataTable like this:

DataTable d_Table = new DataTable();

//fill the DataTable

DataRow[] rowCount = d_Table.Select("secondCol = '111'");
this.lb_qty.Text = rowCount.Length.ToString();

Or you can do it in a foreach -loop:

int count = 0;

foreach(DataGridViewRow dgr in this.dgv_table.Rows)
{
    if(dgr.Cells["secondCol"].Value.ToString() == "111") count++;
}
this.lb_qty.Text = count.ToString();
int CountValues(string input, string searchedValue, int ColumnNumber, bool skipFirstLine = false)
{
                int numberOfSearchedValue= 0;
                string line;

            using (StreamReader reader = new StreamReader (input))
            {
                if(skipFirstLine)
                    reader.ReadLine();

                while ((line = reader.ReadLine()) != null)
                {
                    if(line.Split(';')[ColumnNumber] == searchedValue)
                       numberOfSearchedValue++;
                }
            }
      return numberOfSearchedValue;
}

Edit: StreamReader.ReadLine() reads the line but also, using this method we are jumping to second line. If there is no more lines it returns null, so that is our ending condition. Rest of the code is readable, I think :)
Didn't test that so be careful :)
It might be necessary to use Trim() or ToUpperCase() in some places (as usually when you are searching).

you can use this method to save the CSV into List of arrays List

public static List<string[]> readCSV(String filename)
{
    List<string[]> result = new List<string[]>();
    try
    {
        string[] line = File.ReadAllLines(filename);
        foreach (string l in line)
        {
            string[] value= vrstica.Split(',');
            result.Add(value);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("Error: '{0}'", e);
    }
    return result;
}

every array will represent a column, so you can simply find the frequency of any value using LINQ or even loop:

foreach (var item in tmp[1].GroupBy(c => c))
                {
                    Console.WriteLine("{0} : {1}", item.Key, item.Count());
                }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM