Trouble formatting string from DataTable - c#

I'm saving a numeric value into a datatable cell (no datatype for the cell has been explicitly declared), then later retrieving that data and trying to format it into a string. Problem is that nothing I've tried will properly format the string.
50000 --> 50,000
I've tried (where r is the row in a loop):
String.Format("{0:0,0}", r["columnName"])
r["columnName"].ToString("n0")
And several variations without any luck. Most of the time I just get the number without the comma.

String.Format("{0:0,0}",int.Parse(r["columnName"].ToString()))

Probably not the most elegant solution, but you could just iterate backwards from the tail-end of the string (or from the decimal point) adding a comma every three characters until you run out.

It might be helpful to have more context for what you're trying to do, but here is an example of getting a value out of a DataTable and then formatting it as desired.
DataTable dt = new DataTable();
dt.Columns.Add( "cellName", typeof( double ) );
dt.Rows.Add( 123.45 );
string val = ( (double)dt.Rows[0]["cellName"] ).ToString( "N" ); // val = "123.45"
I'm explicitly casting the value back to a double before calling ToString. You could also call string.Format on that value instead of ToString and it should work just as well.
EDIT: If you're storing the value as a string and then want to format it, use this:
string val = ( double.Parse( dt.Rows[0]["cellName"] ) ).ToString( "N" );
This does assume that the value is parsable though (i.e. isn't null).

The problem with these methods is that depending on the structure of the underlying table that field may be null. If you try to cast a null value held as an object (in the DataTable) to string,integer, decimal, or what have you... your app will blow up 100% of the time. Unless your DataSet is a strongly typed data set you will always want to do this error checking. As a matter of fact, writing a small data reading class to read string, decimals, date times, integers, whatever... is a must in any Data access operations having to do with Database....
So here is more error proof approach which idealy should be wrapped in a helper method as shown here:
public static string GetFormatedDecimalString(DataRow row, string columnName, string format)
{
string ColumnNameStringValue = String.Empty;
decimal ColumnNameValue = Decimal.Zero;
if( row[columnName) == DBNull.Value )
{
ColumnNameValue = Decimal.Zero;
}
else
{
ColumnNameStringValue = row[columnName].ToString();
if( ! Decimal.TryParse(ColumnNameStringValue, out ColumnNameValue )
{
ColumnNameValue = Decimal.Zero;
}
// if the if statement evaluated to false the ColumnNameValue will have the right
// number you are looking for.
}
return ColumnNameValue.ToString(format);
}
passing "N" or "{0:0,0}" as the format string will work just fine.

Related

Null value causing issue saving to the database

I am trying to convert a text box into a decimal when I try this method it says that inpurt string was not in correct format what is the best way around this.
_record.houseHoldArrearsAmount = Convert.ToDecimal(txtArrearsAmount.Text)
I persume it is because text is "" null and and 0.00 hence it falls over
The compiler run time is causing an exception
The input is blank if the user has not entered a value as of yet
If you know that the text is always going to be a number you can still use Convert but check that the string isn't empty first:
if (!string.IsNullOrWhitespace(txtArrearsAmount.Text))
{
_record.houseHoldArrearsAmount = Convert.ToDecimal(txtArrearsAmount.Text);
}
Obviously this won't update the houseHoldArrearsAmount if it's not a numeric value. What you do in this case depends on your business model. You might want to set it to 0 or you might want to leave it with the old value and report and error.
Alternatively, if the input could be any string, you can use Decimal.TryParse to convert the string to a number.
decimal result;
if (decimal.TryParse(txtArrearsAmount.Text, out result))
{
_record.houseHoldArrearsAmount = result;
}
You can use "TryParse" funtion.
decimal householdArrearsAmount = decimal.Zero;
decimal.TryParse(txtArrearsAmount.Text, out householdArrearsAmount);
_record.householdArrearsAmount = householdArrearsAmount;
You can't use the null coalescing operator (as your suggested in comments), as the string value of the textbox won't be null, it will be an empty string.
You could do the following:
_record.householdArrearsAmount =
(string.IsNullOrWhiteSpace(txtArrearsAmount.Text) ? 0 :
Convert.ToDecimal(txtArrearsAmount.Text));

Replace string value with '0' when string is empty

I'm taking a value from a textbox and converting it to decimal. But, the textbox value could be empty. So, how could I handle empty strings from the textbox?
Unfortunately I have around 50 textboxes to deal with, so answers like 'check for null with IF condition' won't help me. My code will look ugly if I use all those IF conditions.
I have this
Convert.ToDecimal(txtSample.Text)
To handle nulls, I did this
Convert.ToDecimal(txtSample.Text = string.IsNullOrEmpty(txtSample.Text) ? "0" : txtSample.Text)
But, the above code is displaying '0' in the textbox. User does not want to see '0'. Another solution is to take text box value into a variable and convert the variable like below.
string variable = txtSample.Text;
Convert.ToDecimal(variable = string.IsNullOrEmpty(variable) ? "0" : variable)
But again, I do not want to define around 50 variables. I am looking for some piece of code that handles null values during conversion without adding the extra line of code.
But, the above code is displaying '0' in the textbox. User does not want to see '0'.
This is because your statement is assigning the new value to txtSample.Text (when you do txtSample.Text = ...). Just remove the assignment:
Convert.ToDecimal(string.IsNullOrEmpty(txtSample.Text) ? "0" : txtSample.Text)
To make things easier if you have many text fields to handle, you can define an extension method :
public static string ZeroIfEmpty(this string s)
{
return string.IsNullOrEmpty(s) ? "0" : s;
}
And use it like this:
Convert.ToDecimal(txtSample.Text.ZeroIfEmpty())
You could make a function to keep from copying the code all over the place.
decimal GetTextboxValue(string textboxText)
{
return Convert.ToDecimal(string.IsNullOrEmpty(textboxText) ? "0" : textboxText);
}
and then use it like this:
GetTextboxValue(txtSample.Text);
You can create an extension method for the string as below
public static decimal ToDecimal(this string strValue)
{
decimal d;
if (decimal.TryParse(strValue, out d))
return d;
return 0;
}
Then you can just txtSample.Text.ToDecimal() in every place.

Convert string array value to int when empty string value is possible

I am having trouble converting a value in a string array to int since the value could possibly be null.
StreamReader reader = File.OpenText(filePath);
string currentLine = reader.ReadLine();
string[] splitLine = currentLine.Split(new char[] { '|' });
object.intValue = Convert.ToInt32(splitLine[10]);
This works great except for when splitLine[10] is null.
An error is thrown: `System.FormatException: Input string was not in a correct format.
Can someone provide me with some advice as to what the best approach in handling this would be?
Don't use convert, it is better to use
int.TryParse()
e.g.
int val = 0;
if (int.TryParse(splitLine[10], out val))
obj.intValue = val;
You can use a TryParse method:
int value;
if(Int32.TryParse(splitLine[10], out value))
{
object.intValue = value;
}
else
{
// Do something with incorrect parse value
}
if (splitLine[10] != null)
object.intValue = Convert.ToInt32(splitLine[10]);
else
//do something else, if you want
You might also want to check that splitLine.Length > 10 before getting splitLine[10].
If you're reading something like a CSV file, and there's a chance it could be somewhat complicated, such as reading multiple values, it probably will make sense for you to use a connection string or other library-sorta-thing to read your file. Get example connection strings from http://www.connectionstrings.com/textfile, using Delimited(|) to specify your delimiter, and then use them like using (var conn = new OleDbConnection(connectionString)). See the section in http://www.codeproject.com/Articles/27802/Using-OleDb-to-Import-Text-Files-tab-CSV-custom about using the Jet engine.
I would go with
object.intValue = int.Parse(splitLine[10] ?? "<int value you want>");
if you're looking for the least code to write, try
object.intValue = Convert.ToInt32(splitLine[10] ?? "0");
If you want to preserve the meaning of the null in splitLine[10], then you will need to change the type of intValue to be of type Nullable<Int32>, and then you can assign null to it. That's going to represent a lot more work, but that is the best way to use null values with value types like integers, regardless of how you get them.

C# Regex.Match to decimal

I have a string "-4.00 %" which I need to convert to a decimal so that I can declare it as a variable and use it later. The string itself is found in string[] rows. My code is as follows:
foreach (string[] row in rows)
{
string row1 = row[0].ToString();
Match rownum = Regex.Match(row1.ToString(), #"\-?\d+\.+?\d+[^%]");
string act = Convert.ToString(rownum); //wouldn't convert match to decimal
decimal actual = Convert.ToDecimal(act);
textBox1.Text = (actual.ToString());
}
This results in "Input string was not in a correct format." Any ideas?
Thanks.
I see two things happening here that could contribute.
You are treating the Regex Match as though you expect it to be a string, but what a Match retrieves is a MatchGroup.
Rather than converting rownum to a string, you need to lookat rownum.Groups[0].
Secondly, you have no parenthesised match to capture. #"(\-?\d+\.+?\d+)%" will create a capture group from the whole lot. This may not matter, I don't know how C# behaves in this circumstance exactly, but if you start stretching your regexes you will want to use bracketed capture groups so you might as well start as you want to go on.
Here's a modified version of your code that changes the regex to use a capturing group and explicitly look for a %. As a consequence, this also simplifies the parsing to decimal (no longer need an intermediary string):
EDIT : check rownum.Success as per executor's suggestion in comments
string[] rows = new [] {"abc -4.01%", "def 6.45%", "monkey" };
foreach (string row in rows)
{
//regex captures number but not %
Match rownum = Regex.Match(row.ToString(), #"(\-?\d+\.+?\d+)%");
//check for match
if(!rownum.Success) continue;
//get value of first (and only) capture
string capture = rownum.Groups[1].Value;
//convert to decimal
decimal actual = decimal.Parse(capture);
//TODO: do something with actual
}
If you're going to use the Match class to handle this, then you have to access the Match.Groups property to get the collection of matches. This class assumes that more than one occurrence appears. If you can guarantee that you'll always get 1 and only 1 you could get it with:
string act = rownum.Groups[0];
Otherwise you'll need to parse through it as in the MSDN documentation.

How to retrieve 0 as the first number in C#

scenario:
I have a database having a record 001234 and I am calling it with cmd.executescaler(); into a int variable. The problem is when I retrieve the saved data (001234) data from that variable it gives only 1234. 00 in 001234 are important, this was the problem first coming in db where sql omits the first zero's then I changed the datatype to nvarchar which works, how I can retrieve the data on the form exactly 001234.
Note: I cannot take the data into string as I have to also apply some calculations on them.
using Sql Server visual studio 2010 c#
Hope it is clear not vague. If you need more information tell me.
Thanks in advance.
Numeric datatype don't have and can't have leading zeros. So the only way to have leading zeros is to store the value as a string.
However, this is just a matter of formatting the output that is shown to the user. You can read the database value into an int variable, do your calculations and when showing the value, you can do:
string displayValue = String.Format("{0:D6}", intValue);
and show the value of displayValue.
If you want to work on the Code side:
string displayValue = String.Format("{0:D6}", intValue);
If you want to work on the DB side you need a Pad function that allows to write this kind of query:
SELECT dbo.PadString ('8', '0', 5)
->Result: 00008
SELECT dbo.PadString ('abc', '*', 12)
->Result: *********abc
SELECT dbo.PadString ('abc', '0', 7)
->Result: 0000abc
Create a function in T-SQL
CREATE FUNCTION [dbo].[PadString]
(#Seq varchar(16),
#PadWith char(1),
#PadLength int
)
RETURNS varchar(16) AS
BEGIN
declare #curSeq varchar(16)
SELECT #curSeq = ISNULL(REPLICATE(#PadWith, #PadLength - len(ISNULL(#Seq ,0))), '') + #Seq
RETURN #curSeq
END
If those leading zeros have some meaning and can't be left out, conversion can be done:
int number = 0;
string strNumber = (string)cmd.ExecuteScalar();
if(int.TryParse(strNumber, out number))
{
// process number
// if you want some output to be formatted with leading
// zeros you can use PadLeft method
int totalNumberOfDigits = 6;
string strResult = number.ToString().PadLeft(totalNumberOfDigits, '0');
}
you can use string.PadLeft() in c# after retrieving your number, as you have fixed length numbers
example from msdn,
string str = "forty-two";
char pad = '.';
Console.WriteLine(str.PadLeft(15, pad)); // Displays "......forty-two".
Console.WriteLine(str.PadLeft(2, pad)); // Displays "forty-two".
The reason SQL does this is because 001234 = 1234 in any number format no matter what type it is. As a "Dirty" solution you could cast it as an int which will give you 1234, perform your calculations and then cast your answer back to string adding the leading zeros.
int myValue = Int32.Parse("001234");
int myAnswer = myValue * 2;
string myAnswerString = "00" + myAnswer.ToString();
The best way to go though would be to format your string as suggested by #Thorsten Dittmar. If possible, do not store numeric values in the database as varchar to begin with, however I know that this is sometimes a requirement, but the I cannot see the point on doing calculations on those values.

Categories