Reputation: 117
I have a unit converter written in Visual Basic, using Visual Studio 2013. The program is working fine until the user's initial input is a decimal point. I get this error message: Conversion from string "." to type 'Decimal' is not valid. How can I get this program to accept a decimal point as the initial input from the user without the program crashing? Code is below.
Private Function GetLength1(ByVal decLengthUnit1 As Decimal) As Decimal
Dim decResult1 As Decimal
If cboUnitType.SelectedItem = "Length" Then
' converts kilometer to...
If cbo1.SelectedItem = "Kilometer" Then
If cbo2.SelectedItem = "Kilometer" Then
decResult1 = txtUnit1.Text
ElseIf cbo2.SelectedItem = "Meter" Then
decResult1 = (decLengthUnit1 * 1000)
ElseIf cbo2.SelectedItem = "Centimeter" Then
decResult1 = (decLengthUnit1 * 100000)
ElseIf cbo2.SelectedItem = "Millimeter" Then
decResult1 = (decLengthUnit1 * 1000000)
ElseIf cbo2.SelectedItem = "Mile" Then
decResult1 = (decLengthUnit1 * 0.621371191)
ElseIf cbo2.SelectedItem = "Yard" Then
decResult1 = (decLengthUnit1 * 1093.613297)
ElseIf cbo2.SelectedItem = "Foot" Then
decResult1 = (decLengthUnit1 * 3280.83989)
ElseIf cbo2.SelectedItem = "Inch" Then
decResult1 = (decLengthUnit1 * 39370.07868)
End If
End If
End If
Return decResult1.ToString().Trim("0") ' this is where I convert the data back to a string with some formatting
End Function
Private Sub txtUnit1_TextChanged(sender As Object, e As EventArgs) Handles txtUnit1.TextChanged
' convert string to numeric data type
Decimal.TryParse(txtUnit1.Text, decUnit1) ' this is where I convert user input to decimal data type
' handle String.Empty, or negative sign
If txtUnit1.Text = "" OrElse txtUnit1.Text = "-" Then
txtUnit2.Text = ""
ElseIf cboUnitType.SelectedItem = "Length" Then
suppressTextBox2TextChanged = True
txtUnit2.Text = GetLength1(decUnit1)
suppressTextBox2TextChanged = False
End If
End Sub
Upvotes: 2
Views: 14069
Reputation: 7244
Your function is set to return to a Decimal value
Private Function GetLength1(ByVal decLengthUnit1 As Decimal) As Decimal
You can either change that to As String
Private Function GetLength1(ByVal decLengthUnit1 As Decimal) As String
Or you can change the Return
Return Ctype(decResult1.ToString().Trim("0"), Decimal)
It could also be that the Decimal
expects a ,
instead of .
I think it has to do with the Culture settings you have. Then you could change the values you have written or do a REPLACE
Replace(decResult1.ToString().Trim("0"),".",",")
EDIT
You could also try to change the txtUnit2.Text = GetLength1(decUnit1)
Change it to txtUnit2.Text = GetLength1(decUnit1).ToString().Trim("0")
and remove the .Trim from inside the Function.
Now you are amending the .Text for the Textbox, then its using the allready obtained Decimal
value.
Upvotes: 3
Reputation: 5752
Hint: I was trying to come up with some code for number validation for my own learning just before you posted your question and I got this far, I would not say it is fully tested, but I did not catch bugs so far:
Class Program
Private Shared Sub Main(args As String())
'For testing, culture string nl-BE allows , as a decimal separator
Dim d As Decimal = CheckNum(".", String.Empty)
Console.WriteLine(d.ToString())
Console.Read()
End Sub
Private Shared Function CheckNum(parm_toParseStr As String, parm_cultureName As String) As Decimal
'Convert the string sent to decimal value and raise an exception if conversion falils
'Expects string to validate and culture name (e.g. en-US). If culture name not passed, current is used
'Takes care of the missing feature in try parse, namely when a string of only "." is passed, tryparse
' does not convert it to 0.
Dim style As NumberStyles
Dim culture As CultureInfo
Dim result As Decimal
If String.IsNullOrEmpty(parm_cultureName) Then
parm_cultureName = Thread.CurrentThread.CurrentCulture.Name
End If
'for style see: http://msdn.microsoft.com/en-us/library/system.globalization.numberstyles%28v=vs.110%29.aspx
style = NumberStyles.Number Or NumberStyles.AllowLeadingSign
culture = CultureInfo.CreateSpecificCulture(parm_cultureName)
parm_toParseStr = parm_toParseStr.Trim()
If String.IsNullOrEmpty(parm_toParseStr) Then
parm_toParseStr = "0"
End If
' Gets a NumberFormatInfo associated with the passed culture.
Dim nfi As NumberFormatInfo = New CultureInfo(parm_cultureName, False).NumberFormat
If parm_toParseStr = "+" OrElse parm_toParseStr = "-" OrElse parm_toParseStr = nfi.CurrencyDecimalSeparator Then
'+ - and decimal point
parm_toParseStr = "0"
End If
'for tryparse see: http://msdn.microsoft.com/en-us/library/ew0seb73%28v=vs.110%29.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2
If [Decimal].TryParse(parm_toParseStr, style, culture, result) Then
Return result
Else
Throw New ArgumentNullException("Could not convert the passed value of:{0}", parm_toParseStr)
End If
End Function
End Class
Upvotes: 0
Reputation: 46365
If you have situations where an error occurs, you can often do the following:
val = 0
On Error Resume Next
val = someStatementThatMayCauseAnError
On Error Goto 0 ' turns error handling off again
This will return 0
for any inputs that could not be parsed.
Of course you could also use error handling to tell the user to try again:
On Error Goto whoops
myString = contentsOfTextBox
val = convert(myString)
Exit Function
whoops:
MsgBox "Cannot convert " & myString & "; please try again"
End Function
Finally - you could explicitly test for the string that gives trouble. But if you have a valid string that causes a problem, it may be that the problem is with your parsing function. Is there an issue with decimal points vs commas, for instance?
Upvotes: 0