Zack
Zack

Reputation: 117

Conversion from string "." to type 'Decimal' is not valid

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

Answers (3)

Mad Dog Tannen
Mad Dog Tannen

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

NoChance
NoChance

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

Floris
Floris

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

Related Questions