1

I want to do method calculation in c# but when I run the code, give me error in converting value. the message error is "Object cannot be cast from DBNull to other types". The error begin at line int bal=0;

 private void btn_total_Click(object sender, EventArgs e)
    {

        //int[] columnData = (from DataGridViewRow row in dataGridView3.Rows where row.Cells[2].FormattedValue.ToString() != string.Empty select Convert.ToInt32(row.Cells[2].FormattedValue)).ToArray();
        //lbl_sum.Text = columnData.Sum().ToString();

        int sum = 0;
        for (int i = 0; i < dataGridView3.Rows.Count; ++i)
        {
            sum += Convert.ToInt32(dataGridView3.Rows[i].Cells[2].Value);
        }

        int bal = 0;
        for (int i = 0; i < dataGridView3.Rows.Count; ++i)
        {
            bal = Convert.ToInt32(dataGridView3.Rows[i].Cells[3].Value) - sum;
        }


        if (bal <0)
        {
            label_bal_pay.Text = bal.ToString();
        }
        else
        {
            lbl_bal.Text = bal.ToString();
        }


        label_bal_pay.Text = bal.ToString();
        lbl_bal.Text = bal.ToString();
        lbl_sum.Text = sum.ToString();
   }
d_matteo
  • 39
  • 6
  • 1
    Add error's full description to the question. Also it won't be bad if you try to debug your code and understand what is wrong by yourself. Probably your error is given as `dataGridView3.Rows[i].Cells[3].Value` can contain value that is not integer. – Samvel Petrosov Jun 20 '17 at 07:54
  • i already edit the description. The value in the column is integer. @S.Petrosov – d_matteo Jun 20 '17 at 08:00
  • Don't perform calculations on the *grid*, do that on the actual data, whether that's a datagrid or list of objects. You won't have to parse strings in this case – Panagiotis Kanavos Jun 20 '17 at 08:04
  • I will check this first @S.Petrosov . thanks – d_matteo Jun 20 '17 at 08:11

2 Answers2

0

Possibly, the values inside dataGridView3.Rows[i].Cells[3].Value are DBNull.Value. A DBNull.Value can not be converted to Int32. This means that the expression Convert.ToInt32(dataGridView3.Rows[i].Cells[3].Value) will fail.

First test if the contents of the Value is DBNull.Value. If so, skip it.

if (dataGridView3.Rows[i].Cells[3].Value != DBNull.Value)
     bal = Convert.ToInt32(dataGridView3.Rows[i].Cells[3].Value) - sum;
Martin Mulder
  • 12,642
  • 3
  • 25
  • 54
  • This is the same thing as the answer I have provided for duplicate. – Samvel Petrosov Jun 20 '17 at 08:26
  • @S.Petrosov: Assuming you're the one downvoting: If this is the same answer than it MUST BE a correct answer! Why the downvote? I did follow rules from stackoverflow. Where did you answer? In the comments? That is also great, but the comments are not meant for answers. Furthermore: I did not read your comment first. – Martin Mulder Jun 20 '17 at 09:09
  • Because this is duplicate question and must be marked as duplicate instead of providing the same answer – Samvel Petrosov Jun 20 '17 at 09:14
  • @S.Petrosov: You are possibly right... But 1) I did not know that duplicate question. 2) It does not invalidate a correct answer. 3) Closing is done by voting. The voting process is not complete, that is why answers are still allowed. – Martin Mulder Jun 20 '17 at 09:18
  • @S.Petrosov: For more discussion about this subject, I refer to: https://meta.stackoverflow.com/questions/253735/is-it-wrong-to-downvote-a-good-answer-to-a-duplicate-question and https://meta.stackoverflow.com/questions/252009/should-there-be-a-deterrent-for-answering-obvious-duplicate-questions – Martin Mulder Jun 20 '17 at 09:21
  • I already found what's the problem and the idea come when I read comment from all of you. So, thank you guys for helping me. – d_matteo Jun 21 '17 at 01:59
-1

It means in your grid there are null values. Try like this

 private void btn_total_Click(object sender, EventArgs e)
 {
    //int[] columnData = (from DataGridViewRow row in dataGridView3.Rows    where row.Cells[2].FormattedValue.ToString() != string.Empty select Convert.ToInt32(row.Cells[2].FormattedValue)).ToArray();
        //lbl_sum.Text = columnData.Sum().ToString();

        int sum = 0;
        for (int i = 0; i < dataGridView3.Rows.Count; ++i)
        {
            if (dataGridView3.Rows[i].Cells[2].Value != null && dataGridView3.Rows[i].Cells[2].Value != DbNull.Value)
                sum += Convert.ToInt32(dataGridView3.Rows[i].Cells[2].Value);
        }

        int bal = 0;
        for (int i = 0; i < dataGridView3.Rows.Count; ++i)
        {
            if (dataGridView3.Rows[i].Cells[3].Value != null && dataGridView3.Rows[i].Cells[3].Value != DbNull.Value)
                bal = Convert.ToInt32(dataGridView3.Rows[i].Cells[3].Value) - sum;
        }

        if (bal < 0)
        {
            label_bal_pay.Text = bal.ToString();
        }
        else
        {
            lbl_bal.Text = bal.ToString();
        }


        label_bal_pay.Text = bal.ToString();
        lbl_bal.Text = bal.ToString();
        lbl_sum.Text = sum.ToString();       
 }

You can do your null control while filling your grid too. If you use ADO.NET, you can use COALESCE methode.

For exemple if

   SELECT column FROM TableName

query can return null values but if you type

  SELECT COALESCE (column, 0) FROM TableName

this time, if the value is null, it will return 0 instead.

Coskun Ozogul
  • 2,389
  • 1
  • 20
  • 32
  • Your newly added if-statements have three opening parantheses and one closing... I'll suggest to rewrite your suggestion. – Martin Mulder Jun 20 '17 at 08:16