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.
Below code which I am using right now does not give what I require.
textBox1.Text = textBox1.Text + enteredvalue;
I would like to achieve entering decimal value in text box without having to enter ".".
If 3 is entered, the output in text box should be 00.03, and then if 5 is entered the output should be 00.35 and so on.
How do I achieve it?
EDIT: I achieved it by creating a method and calling it everytime i press the input number.
public void dropcashvalue(string inputdigit)
{
if (txtDropCash.Text == "00.00")
{
txtDropCash.Text = "";
this.dropstring = "";
}
this.dropstring = this.dropstring + inputdigit;
txtDropCash.Text = (Convert.ToDouble(this.dropstring) / 100).ToString("F2");
}
My textbox and inputnumber design looks like this.
You need to maintain an additional variable for your compund value.
double enteredValue = 0.0;
Whenever a new digit comes in you add it to your value:
enteredValue = enterValue*10 + inputDigit;
Inthe Textbox you show a formatted version of your value:
textBox.Text = (enteredValue/100).ToString("F2");
I have a DataGridView in which I have multiple rows say (15 rows). I want to add some columns value and store them in an array using foreach loop. Then I want to display the array (with multiple strings) in another form.
Currently I am using stringBuilder to store the strings and display, but it only display the last string store in it.
StringBuilder listOrderStatus = new StringBuilder();
foreach (DataGridViewRow rw in grdData.Rows)
{
string _idNumber = rw.Cells[6].Value.ToString();
string _orderNo = rw.Cells[13].Value.ToString();
double _ordTotalSpace = double.Parse(rw.Cells[17].Value.ToString());
double _ordDoneSpace = double.Parse(rw.Cells[18].Value.ToString());
double _ordRmainSpace = double.Parse(rw.Cells[19].Value.ToString());
double _TotalSpace = getTotalArea();
double _DoneSpace = getDoneArea();
double _RmainSpace = getRmainArea();
if(_ordTotalSpace ! = _TotalSpace){
string value = "Invalid Order: Order number" + _orderNo + "ID No." + _idNumber;
//I want to store this string in the array
listOrderStatus.Append(value);
listOrderStatus.AppendLine();
}
else{
string value2 = "Valid Order: Order number" + _orderNo + "ID No." + _idNumber;
//I want to store this string in the array
listOrderStatus.Append(value2);
listOrderStatus.AppendLine();
}
}
string innerString = listOrderStatus.ToString();
//This a new form to display strings in simple multiline-TextBox (Never mind, this is client request :P)
var myForm = new Other.frmDisplayData();
myForm._clist = innerString;
myForm.Show();
Can any one guide me. Thanks in advance
Are you insisting on using StringBuilder?! if not you can use something like below:
Define as global and instead of StringBuilder:
List<string> listOrderStatus = new List<string>();
And then
string value = "Invalid Order: Order number" + _orderNo + "ID No." + _idNumber;
listOrderStatus.Add(value);
then
myForm._clist = listOrderStatus;
Note:
You have to define _clist as a List of strings like first code line I wrote.
in this case it's not needed to use new line .but if you will want to use do like below:
string value = "Invalid Order: Order number" + _orderNo + "ID No." + _idNumber;
value += System.Environment.NewLine;
you can also use Dictionary definition :
Dictionary<int,string> Name = new Dictionary<int,string>();
How is _clist used to assign to multiLineTextBox.Text?
multilineTextBox.Multiline = true;
multilineTextBox.Scrollbars = Scrollbars.Both;
multilineTextBox.Text = _clist;
This would at least be the minimum of what you would need? Are you able to see in Debug that the _clist has the entire string that you're wanting to display?
I have a multiline text box called txtOutput that receives messages from the serial port. Each new message is a new line and represents a number from 1 to a maximum of 4 digits.
The method used to add the data in the multiline textbox is an append.
I have no problems with the above feature, it is working fine.
I would like to take the last message from the txtOutput and show it in textBox2 if the number is less than 1000, and in textbox3 if it is not. Then both text boxes would be updated.
I would appreciate if someone can give in an example especially in how to get the last message from the multiline textbox to a variable and how to update the textboxes if there is a new value.
You should save the last message (from the serial port) in a variable such as lastSerialMesssage. You can then convert this value to an integer and use a conditional statement to check if the value is smaller than 1000, if it is, set TextBox3 to the last serial message value, else set the value to TextBox2.
string lastSerialMessage = SerialPortMessage;
int lastMessageValue;
Int32.TryParse(lastSerialMessage, out lastMessageValue);
if (lastMessageValue < 1000)
{
TextBox3.Text = lastSerialMessage;
} else {
TextBox2.Text = lastSerialmessage;
}
http://msdn.microsoft.com/en-us/library/f02979c7.aspx
Thanks to all for the suggestions but as I mentioned in my comments, the suggested methods did not work because the content of the string was not accurate and I ended up receiving in the textBox 2 and 3 only part of the data and not always. I have solved the problem (thanks to other advices) using RegEx in this way:
if (txtOutput.Text.Length > 0)
{
MatchCollection mc = Regex.Matches(txtOutput.Text, #"(\+|-)?\d+");
if (mc.Count > 0)
{
long value = long.Parse(mc[mc.Count - 1].Value);
if (value < 1000)
{
textBox2.Text = value.ToString();
}
else
{
value = value - 1000;
textBox3.Text = value.ToString();
}
}
}
this is working fine and no piece of information are lost.Thanks again for your advices.
Hi I was wanting to display the number of characters entered into a textbox and I want it to update as I type how can I go about this?
Here is what I have:
int kk = textBox1.MaxLength;
int jj = //This is what I need to know.
string lol = jj.ToString() + "/" + kk.ToString();
label2.Text = lol;
How about
int jj = textBox1.Text.Length;
Or am I missing something?
The text of the text box will be a string, so it has a Length property, i.e.:
textBox1.Text.Length
TextBoxobject.Text.Length will give you the length of textbox value.
you can use the OnTextChanged event of the Textbox on the client side in Javascript and compute the increment from.