How to get TrimEnd() to stop at a specific character - vb.net

I have a series of percentage values saved in a database that look something like this:
Percentage
_____________
100.00000
50.00000
74.02500
When I display the values to the screen, I'd like to trim unnecessary zeroes from the end of the string along with the decimal point so the above examples become:
Percentage
_____________
100
50
74.025
I'm currently using the following code:
displayVal = rawVal.TrimEnd({"0"c, "."c})
but this code continues to trim after the decimal if there are additional zeroes. I also tried:
displayVal = rawVal.TrimEnd(New String({"0", "."}))
which almost works. It just leaves the decimal point.
Is there a way to do what I want using TrimEnd() or do I need to switch to regex?

As Tim already mentioned in the comments, if the data type in the DB is already some numerical type, it would be best to keep it in that type and then use the appropriate numeric formatting when converting it to a string for output. If, however, the input data is already a string, then that's not an option. In that cast, the simplest option is to just do two trims in series, like this:
Private Function RemoveUnecessaryZeros(input As String) As String
Return input.TrimEnd("0"c).TrimEnd("."c)
End Function
However, that doesn't give you a lot of flexibility, it doesn't remove preceding zeros, and it does nothing to reformat the string using the current culture. If that matters, you could instead parse the value into a numeric type and then use the desired string formatting options to re-output it to a string. For instance:
Private Function RemoveUnecessaryZeros(input As String) As String
Dim result As Double
If Double.TryParse(input, result) Then
Return result.ToString()
Else
Return input
End If
End Function
However, when you do it that way, you may potentially lose precision along the way, depending on the input numbers and the data type you choose to parse it with. If you need more control over the parsing/reformatting and you want to keep it purely in strings so no precision is lost, then you may want to consider using regex. For instance:
Private Function RemoveUnecessaryZeros(input As String) As String
Dim m As Match = Regex.Match(input, "[1-9]\d*(\.([1-9]|0+[1-9])+)?")
If m.Success Then
Return m.Value
Else
Return input
End If
End Function

Related

Convert numeric data from database

In my system default decimal separator is comma.
In database I have written numeric values as strings but in format with decimal separator point.
Now, when I read data from database like this "3.2" with following code I get value 32D!
NumericUpDown1.Value = CDec(reader("myfield"))
Is here any way that I can get decimal value of 3,2 from showed code in described situation?
You know your number is stored as a string in the format "1,23456". You are dealing with a globalization issue, and as such, you could convert the string using the appropriate culture formatting settings.
NumericUpDown.Value is of type Decimal, so I use the function Convert.ToDecimal.
For this example, I'll assume the number being inserted was stored in the database by a Croatian, so I'd use "hr-HR" for the culture name.
Dim myFieldCroatia As String = "1,2345678901234567890123456789"
NumericUpDown1.Value = Convert.ToDecimal(myFieldCroatia, New Globalization.CultureInfo("hr-HR"))
And if it were stored by an American, I'd use "en-US"
Dim myFieldUnitedStates As String = "1.2345678901234567890123456789"
NumericUpDown2.Value = Convert.ToDecimal(myFieldUnitedStates, New Globalization.CultureInfo("en-US"))
As an aside, if you had first converted to Double, and implicitly converted to Decimal, you would have lost any precision past 15 to 17 decimal places. Not sure if it's required, but it's worthy of noting.
See MSDN for a complete list of culture names
Try this.
NumericUpDown1.Value = CDec(reader("myfield"), new NumberFormatInfo() { NumberDecimalSeparator = "," });
More info
NumericUpDown1.Value = Convert.ToDouble(reader("myfield").ToString().Replace("," , "."))
is another way if you don't want to convert to Double then you could use ToDecimal.
If I were you, I wouldn't use the CDec but the Val function instead.
Try this code :
NumericUpDown1.Value = Val(reader("myfield").ToString().Replace("," , "."))

InvalidCastException Conversion from string "" to type 'Double' is not valid

I'm developing a system that shows the total amount paid of a student from the database. For some students that only have a few transactions the function below gives an error Conversion from string "" to type double... but if a student doesn't have any data entry or the values are zero-to-many the code below encounters it. What should I do? Do I need to adjust the code? Please help.
I have here an Function that gets the total items.
Function Totalpaid() As Double
Dim i As Integer
For i = 0 To ((tbl_receipt.Items.Count) - 1)
Totalpaid = (Totalpaid + tbl_receipt.Items(i).SubItems(3).Text)
Next
End Function
You're trying to add two numbers but one of the operands is not a number. You're assuming that the Text of the subitem will be converted a number and added to the running total. At least one of your subitems is blank though. Maybe you consider that to represent zero but it doesn't. It doesn't represent any number at all so the operation fails.
What you should be doing is validating and converting the subitem contents yourself and then providing the system with two Double values to add. If there is no value then you either ignore that subitem or use zero explicitly. Option Strict On will at least force you to perform the conversion but it's still up to you to provide the validation if there's any chance that the data will not be valid.
To me this looks like a problem with your data rather than the code directly. I would recommend sanitising your data before trying to use it in a calculation, i.e.:
Function Totalpaid() As Double
Dim i As Integer
Dim val as Double
For i = 0 To ((tbl_receipt.Items.Count) - 1)
If Double.TryParse(tbl_receipt.Items(i).SubItems(3).Text, val) Then
Totalpaid = (Totalpaid + val)
End If
Next
Return Totalpaid
End Function
The message Conversion from string "" to type double... is saying that your are trying to convert an empty string to a Double which cannot work.
As a side note, when testing your code I did have to include the line Return Totalpaid, I don't know if this was missed when you where writing out the question.

Validate Standard Numeric Format

I have a Problem with validating a String in vb.net.
I want to check if the inputString is in a valid standard numeric Format according to http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx except "E" and "X"
So i have the Format specifier e.g. "d4" and my inputString like "1999". But the Specifier is unknown at design time.
Is there a way to validate the inputString if it is valid with the given Format specifier
greetz gangfish
UPDATE:
I am writing an Extension for a working programm.
I am adding massprocessing for selected rows from a gridview.
If a row is selected, the values are shown in my inputFields.
The inputFields are from Telerik UI for WinForms(RadMaskedEditBox).
If multiple rows are selected, i have to remove the Masking, because we have to add an Editor-Pattern for alle Entries (Form: {1..5}test).
So i have to validate if the given input is valid for the masking assigned by the main application. So i have no clue what format specifier is given at design time.
But i know that all standard numeric formats except "E" and "X" are supported by the RadMaskedEditBox
I would like to have something like this:
Dim inputValue = "1999"
Dim formatSpecifier = "d4"
Try
ValidateValue(inputValue, formatSpecifier)
Catch ex As Exception
' Validation Failed. Handle it
End Try
A format specifier is just a string. You can substitute it with any string value at runtime, provided that string value is a valid format specifier. (Otherwise I imagine you'll get an error, so you'll want to have some error handling around all of this.)
For example, given the sample code on the link you provided:
decimal value = 123.456m;
Console.WriteLine(value.ToString("C2"));
If you have a format specifier obtained from somewhere else and stored in a string variable, you can just use that variable:
string formatSpecifier = GetFormatSpecifier();
// ...
decimal value = 123.456m;
Console.WriteLine(value.ToString(formatSpecifier));
Or if it's part of a larger string, you can just concatenate it into that string. So where you would normally have this:
decimal value = 123.456m;
Console.WriteLine("Your account balance is {0:C2}.", value);
You might instead have this:
string formatSpecifier = GetFormatSpecifier();
// ...
decimal value = 123.456m;
Console.WriteLine("Your account balance is " + formatSpecifier + ".", value);
(Or you can construct the string with a StringBuilder. You might also use string.Format() to assemble your format specifier, but I imagine that could introduce confusion when supporting that code.)

IsNumeric returns true for strings containing a D character

I had a strange error in a VB6 app this morning and it all stems from the fact that IsNumeric is not working as I expected. Can someone shed some light on why? To me this seems like a bug.
This code displays 4.15877E+62 in a message box:
Dim strMessage As String
strMessage = "0415877D57"
If IsNumeric(strMessage) Then
MsgBox CDbl(strMessage)
Else
MsgBox "not numeric"
End If
I am guessing that the runtime engine is incorrectly thinking that the D is in fact an E?
I think this is a bug though as the exact same code in VB.NET outputs not numeric
Is this a known issue with IsNumeric?
If you check the VB6 docs:
Note Floating-point values can be expressed as mmmEeee or mmmDeee, in which mmm is the mantissa and eee is the exponent (a power of 10). The highest positive value of a Single data type is 3.402823E+38, or 3.4 times 10 to the 38th power; the highest positive value of a Double data type is 1.79769313486232D+308, or about 1.8 times 10 to the 308th power. Using D to separate the mantissa and exponent in a numeric literal causes the value to be treated as a Double data type. Likewise, using E in the same fashion treats the value as a Single data type.
I've been using my own IsNumber function for a long time exactly because of this situation. IsNumeric can also return true for certain money symbols, like this: IsNumeric("$34.20").
My IsNumber function looks like this:
Public Function IsNumber(ByVal Data As String) As Boolean
If Data = "" Then
IsNumber = False
Exit Function
End If
IsNumber = IsNumeric(Data & "e0")
End Function
The idea here is... if there is already an e or d in the data, adding another will cause the data to NOT be numeric using the IsNumeric check. You can easily change this function to only allow for integers by replacing "e0" with ".0e0". Want just positive integers? then use this: IsNumeric("-" & Data & ".0e0")
The only downside of this method is that an empty string normally is not numeric, but when you append "e0" to it, it becomes numeric so you need to add a check for that, like I did in my code.
I suggest making a custom validator. Do you want to allow 0-9 only? What about negatives? Commas? I never cared for Microsoft's implementation, but I understand it.

adding variables numical values (newb question)

Yesterday i had a look at how to set values of variables from nummbers stored in external txt files
the variables then needed to be added up so i used trial and error first
((XVAL) + (NEWVAL))
assuming that XVAL was set to 10 and NEWVAL was set to 20 i expected to get the answer of thirty but waqs presented with the new value of 10 20
VB.net pysicaly added the two values together but i wanted the mathematical product of the two which is ((10) + (20)) = 30
yep its a newb question could anyone explain how to achieve what im affter
XVAL and NEWVAL are strings, so they are simply being concatenated together. You need to convert them to integers, so that VB.NET will treat them as such. To do this, use the Int32.Parse() method.
Dim intXVAL As Integer = Int32.Parse(XVAL)
Dim intNEWVAL as Integer = Int32.Parse(NEWVAL)
Dim result = intXVAL + intNEWVAL
You want to cast them to a number first.
Try CDbl.
See http://msdn.microsoft.com/en-us/library/Aa263426 for more.
edit: Oops, thought you were talking about VBA.
Try using Double.Parse(YOURVALUE) if you're talking about VB.NET.
Have you tried the Val() function?
Val(XVAL) + Val(NEWVAL)
The + operator in VB.NET (for backwards-compatibility reasons) means both add and concatenate depending on the types of the variables it is being used with. With two numeric types (Integer, Single, Double, etc.), it adds the values together as you would expect. However, with String types, it concatenates the two strings.
Presumably, then, your XVAL and NEWVAL variables are String types because they're being read out of a text file, which is causing VB.NET to concatenate them into a new string instead of add them together. To get the behavior you're expecting, you need to convert them to numeric types.
Some of the other answers suggest casting simply casting the string values to numeric types (CInt, CSng, CDbl, etc.), but this may not work as expected if the value contained by your string cannot be converted to number. The Int32.Parse method will throw an exception if the value held by your string cannot be represented as a number. This is especially important to keep in mind if you're reading values from a text file that are not guaranteed to adhere to any particular constraints.
Instead, you probably want to use something like Int32.TryParse, which returns a Boolean value indicating whether or not the conversion succeeded and will not throw an exception.
As you are reading from a text file I assume that you are reading your values out as strings, so when you do this:
((XVAL) + (NEWVAL))
It is effectively concatenating the two strings together. In order to get the mathematical product of the two values these need to be int/integers which is the number type.
There are a number of ways you can do this, but in essence you have to 'cast' the strings to ints and then do your calculation.
So in vb.net it would be something like this (pseudo code):
Dim xval As String = "10"
Dim newval As String = "20"
Dim x As Integer = Int32.Parse(xval)
Dim n As Integer = Int32.Parse(newval)
Dim prod As Integer = x + n
Console.WriteLine(prod)
There are a number of other methods of doing this, for example using:
int.Parse(...)
or
Integer.TryParse(...)
More information on these sorts of type conversions can be found here:
http://dotnetperls.com/integer-parse-vbnet
One thing to bear in mind with these sorts of conversions is that you have to be certain that your input data is convertable. Otherwise your code will throw exceptions. This is where TryParse is useful as you can use this to check the inputs and handle invalid inputs without the need for exceptions.