【问题标题】:Conversion from string "." to type 'Decimal' is not valid从字符串“.”转换键入“十进制”无效
【发布时间】:2022-02-01 23:41:12
【问题描述】:

我有一个用 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

【问题讨论】:

  • "用户的初始输入是."。您不能检查该值的文本并进行转换吗?或者将值设置为零,然后执行On Error Resume Next,然后转换 - 如果没有错误,则该值被覆盖,否则它将为零。
  • 代码中的哪一行导致了问题?
  • @Floris - 我已经在尝试使用 TryParse 方法对其进行转换,但出现错误。你建议我用什么转换它?
  • @EmmadKareem - 这是程序停止的地方:Return decResult1.ToString("N").Trim("0")
  • 扎克,你让它工作了吗?

标签: vb.net


【解决方案1】:

您的函数设置为返回小数值

Private Function GetLength1(ByVal decLengthUnit1 As Decimal) As Decimal

您可以将其更改为字符串

Private Function GetLength1(ByVal decLengthUnit1 As Decimal) As String

或者你可以改变返回

Return Ctype(decResult1.ToString().Trim("0"), Decimal)

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

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

编辑

您也可以尝试更改txtUnit2.Text = GetLength1(decUnit1)

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

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

【讨论】:

  • 我按照您的建议将返回类型替换为字符串,并且程序接受零和小数点作为用户的初始输入。谢谢你。现在,我在格式化字符串时遇到问题。我想修剪小数点后的尾随零而不从整体修剪零。您对我的格式有什么建议,我应该在函数中还是在 TextChanged 事件中进行格式设置?
  • 好的,试试我的编辑部分!
  • 好的,我这样做了,程序仍在运行。但是,如果小数点后没有值,则会修剪小数点前的零。例如:将 1 公里转换为厘米给我的结果是 1 而不是 100000,但是将 1.0 公里转换为厘米给我的是正确的 100000,但最后有一个不需要的小数点。结果如下所示:(100000.)。
【解决方案2】:

如果您有发生错误的情况,您通常可以执行以下操作:

val = 0
On Error Resume Next
val = someStatementThatMayCauseAnError
On Error Goto 0       ' turns error handling off again

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

当然你也可以使用错误处理来告诉用户重试:

On Error Goto whoops
myString = contentsOfTextBox
val = convert(myString)
Exit Function
whoops:
MsgBox "Cannot convert " & myString & "; please try again"
End Function

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

【讨论】:

    【解决方案3】:

    提示:在您发布您的问题之前,我试图为我自己的学习提供一些数字验证代码,但我已经走到了这一步,我不会说它已经过全面测试,但到目前为止我还没有发现错误:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-18
      • 2017-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多