简体   繁体   English

格式异常未处理C#

[英]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. 我试图在我的桌面c#应用程序中保存一组记录,但由于其中一个值的格式错误,它似乎停止了。

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: 但是一旦我保存,GrandTotal计算似乎就出现了问题:

在此处输入图片说明

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. 我尝试注释掉所有与GrandTotal相关的值和函数,并且记录开始毫无问题地保存。 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; 1我不会尝试使用convert将textbox.text值转换为Int32; 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. 这样可以确保将文本转换为整数,否则将返回0作为返回值。

Then in your save method - your @GrandTotal parameter is trying to save to what datatype ? 然后在您的save方法中-您的@GrandTotal参数试图将其保存为什么数据类型? - 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. 这就是为什么他在代码中设置参数值= lblGrandtotal.Text的原因,它不是一个带有格式逗号等的数字。他需要删除那些字符才能使其起作用,使用Int.TryParse可以轻松地揭示这一点。

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. 同样,稍后在您的代码中将实际存储为INT int数据库的十进制数。 and as mentioned by ken, use tryparse to convert the value from string to .... 并如ken所述,使用tryparse将值从字符串转换为...。

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. 您正在尝试解析lblGrantotal.Text中的整数,但是正在获取FormatException,这意味着lblGranTotal中的文本无法识别为数字。 Maybe you are using comma , instead of point . 也许你正在使用的不是点逗号 as decimal separator, or something like that. 作为小数点分隔符或类似的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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