简体   繁体   中英

Format Exception was unhandled c#

I'm trying to save a set of records in my desktop c# application and it appears to stop since one of the values was in the incorrect format.

Before saving, the system goes through these computations:

private void ComputeTotalWeight()
    {
        double TotalWeight;
        TotalWeight = ((Convert.ToInt32(txtSmall.Text)) + (Convert.ToInt32(txtMedium.Text)) + (Convert.ToInt32(txtLarge.Text)) + 
            (Convert.ToInt32(txtExtralarge.Text))) * .285;
        txtTotalweight.Text = String.Format("{0:#,##0}", TotalWeight);

    }

    private void ComputeTagsCollars()
    {
        int TagsCollars;
        TagsCollars = Convert.ToInt32(txtSmall.Text) + Convert.ToInt32(txtMedium.Text) 
            + Convert.ToInt32(txtLarge.Text) + Convert.ToInt32(txtExtralarge.Text);
        txtTags.Text = String.Format("{0:#,##0}", TagsCollars);
        txtCollars.Text = String.Format("{0:#,##0}", TagsCollars);

    }

But once I save, it seems to be having a problem with the GrandTotal computation:

在此处输入图片说明

I suspect the error come from this computation:

private void ComputeGrandTotal()
    {
        double GrandTotal;
        GrandTotal = (((Convert.ToInt32(txtSmall.Text) + Convert.ToInt32(txtMedium.Text) + Convert.ToInt32(txtLarge.Text) + 
            Convert.ToInt32(txtExtralarge.Text)) * .285) * 315);

        double TagsCollars;
        TagsCollars = Convert.ToInt32(txtSmall.Text) + Convert.ToInt32(txtMedium.Text) + Convert.ToInt32(txtLarge.Text) + Convert.ToInt32(txtExtralarge.Text);
        txtTags.Text = String.Format("{0:#,##0}", TagsCollars);
        txtCollars.Text = String.Format("{0:#,##0}", TagsCollars);

        lblGrandtotal.Text = String.Format("{0:#,###,##0}", (GrandTotal + TagsCollars + TagsCollars));

    }

I've tried commenting out all GrandTotal related values and functions, and the records begin to save with no problem. Here's a copy of my save function:

private void InsertNewRecord()
    {
        SqlCommand cmdInsert = new SqlCommand();
        cmdInsert.Connection = cn;
        cmdInsert.CommandType = CommandType.Text;
        //cmdInsert.CommandType = CommandType.StoredProcedure;

        cmdInsert.Parameters.AddWithValue("@QtySmall", Convert.ToInt32(txtSmall.Text));
        cmdInsert.Parameters.AddWithValue("@QtyMedium", Convert.ToInt32(txtMedium.Text));
        cmdInsert.Parameters.AddWithValue("@QtyLarge", Convert.ToInt32(txtLarge.Text));
        cmdInsert.Parameters.AddWithValue("@QtyExtralarge", Convert.ToInt32(txtExtralarge.Text));
        cmdInsert.Parameters.AddWithValue("@QtyTags", Convert.ToInt32(txtTags.Text));
        cmdInsert.Parameters.AddWithValue("@QtyCollars", Convert.ToInt32(txtCollars.Text));
        cmdInsert.Parameters.AddWithValue("@TotalWeight", Convert.ToInt32(txtTotalweight.Text));
        cmdInsert.Parameters.AddWithValue("@NoWorkers", Convert.ToInt32(txtWorkersno.Text));
        cmdInsert.Parameters.AddWithValue("@NoMachines", Convert.ToInt32(txtMachinesno.Text));
        cmdInsert.Parameters.AddWithValue("@BomStatus", SqlDbType.VarChar).Value = txtStatus.SelectedItem.ToString();
        cmdInsert.Parameters.AddWithValue("@StartDate", SqlDbType.DateTime).Value = dtpStart.Value;
        cmdInsert.Parameters.AddWithValue("@EndDate", SqlDbType.DateTime).Value = dtpEnd.Value;
        cmdInsert.Parameters.AddWithValue("@GrandTotal", Convert.ToInt32(lblGrandtotal.Text));
        cmdInsert.CommandText = " INSERT INTO BillOfMaterials2 " + " (QtySmall, QtyMedium, QtyLarge, QtyExtralarge, QtyTags, QtyCollars, TotalWeight, NoWorkers, NoMachines, BomStatus, StartDate, EndDate, GrandTotal) VALUES (" + "@QtySmall, @QtyMedium, @QtyLarge, @QtyExtralarge, @QtyTags, @QtyCollars, @TotalWeight, @NoWorkers, @NoMachines, @BomStatus, @StartDate, @EndDate, @GrandTotal)";
        //cmdInsert.CommandText = "spInsertBom";



        cmdInsert.ExecuteNonQuery();
    }

Any help would be much appreciated.

1st I would not attempt converting a textbox.text value to Int32 using convert; better to use

Int32 myint = 0;
Int32.TryParse(textbox.text, out myint) ;

This ensures that the text can be converted to an integer and if not you get 0 as a returned out value.

Then in your save method - your @GrandTotal parameter is trying to save to what datatype ? - what is the type in your database ?? do they match - if not you will get a format exception your data (Type) is not the same Format (type) as the column type.

The op does not have a valid number in the text box he has this:

    lblGrandtotal.Text = String.Format("{0:#,###,##0}", 
(GrandTotal + TagsCollars + TagsCollars));

This is why the code where he sets the parameter value = lblGrandtotal.Text it is not a number it has formatting commas etc.. he needs to remove those to make it work, using Int.TryParse would easily reveal this.

its starts here - first you are putting decimal in your format string with comma.

lblGrandtotal.Text = String.Format("**{0:#,###,##0}**", (GrandTotal + TagsCollars + TagsCollars));

also, later in your code you are storing INT int database, when its actually decimal. and as mentioned by ken, use tryparse to convert the value from string to ....

There are several issues here some of the other posts touched on but, what really stands out (in my opinion) is you're not validating the input data, which is risky for many reasons, asking for future headaches and causing these issues. Also, there are standard numerical input controls you could use. If there's some reason you can't use them though, you should be validating the input and, if the data is not valid, handle it. Below is a quick way to validate and then handle invalid inputs.

private void ComputeGrandTotal()
{
    //Since there are values that need to be validated and converted to integers for use in two calculations...
    int smll, mdm, lg, xl;
    //Validate the inputs can be converted and set the appropriate variable values at the same time
    if (Int32.TryParse(txtSmall.Text, out smll) //using TryParse sets the integer variable values only if they can successfully be converted
        && Int32.TryParse(txtMedium.Text, out mdm)
        && Int32.TryParse(txtLarge.Text, out lg)
        && Int32.TryParse(txtExtralarge.Text, out xl)
        )
    {
        int ttl = smll + mdm + lg + xl;
        double GrandTotal, TagsCollars;
        TagsCollars = ttl;
        GrandTotal = TagsCollars * .285 * 315;

        txtTags.Text = $"{TagsCollars:#,##0}"; //Resharper suggested simplification of String.Format("{0:#,##0}", TagsCollars)....I believe ReSharper
        txtCollars.Text = $"{TagsCollars:#,##0}";
        lblGrandtotal.Text = $"{(GrandTotal + TagsCollars + TagsCollars):#,###,##0}";

    }

}

This will get the job done but it's pretty inflexible. Each input has to successfully convert to an integer or this will fail. A better, more time consuming approach would be something like this:

    int smll;//, mdm, lg, xl;
    try
    {
        smll = Convert.ToInt32(txtSmall.Text);

    }
    catch (FormatException)
    {
        smll = 0;
        //txtSmall.Text value can't be converted to an integer
    }
    catch (Exception)
    {
        //some other issue occurred and you're probably better off just exiting entirely
        return;
    }

There are more flexible approaches out there, such as using number styles and such but, their flexibility comes at the price of you having to be more aware of the impact of what and how you're coding. Sometimes it's just safer to train your customers than write code you're not confident with.

You are trying to parse an integer in lblGrantotal.Text, but you are getting a FormatException, which means the text in lblGranTotal isn't recognized as a number. Maybe you are using comma , instead of point . as decimal separator, or something like that.

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