vb.net 从字符串“.”转换而来 输入“十进制”无效

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20306332/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 15:59:37  来源:igfitidea点击:

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

vb.net

提问by Zack

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.

我有一个用 Visual Basic 编写的单位转换器,使用 Visual Studio 2013。程序运行良好,直到用户的初始输入是小数点。我收到此错误消息:从字符串“转换”。输入“十进制”无效。如何让该程序接受小数点作为用户的初始输入而不会使程序崩溃?代码如下。

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

采纳答案by Mad Dog Tannen

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

您可以将其更改为 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 Decimalexpects 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

也可能是Decimal期望,而不是.我认为这与您拥有的文化设置有关。然后你可以改变你写的值或做一个REPLACE

Replace(decResult1.ToString().Trim("0"),".",",")

Replace(decResult1.ToString().Trim("0"),".",",")

EDIT

编辑

You could also try to change the txtUnit2.Text = GetLength1(decUnit1)

你也可以尝试改变 txtUnit2.Text = GetLength1(decUnit1)

Change it to txtUnit2.Text = GetLength1(decUnit1).ToString().Trim("0")and remove the .Trim from inside the Function.

将其更改为 txtUnit2.Text = GetLength1(decUnit1).ToString().Trim("0")并从函数内部删除 .Trim。

Now you are amending the .Text for the Textbox, then its using the allready obtained Decimalvalue.

现在您正在修改文本框的 .Text,然后使用已经获得的Decimal值。

回答by Floris

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 0for any inputs that could not be parsed.

这将返回0任何无法解析的输入。

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?

最后 - 您可以显式测试出现问题的字符串。但是,如果您有一个导致问题的有效字符串,则问题可能出在您的解析函数上。例如,小数点与逗号是否存在问题?

回答by NoChance

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