none
An unhandled exception of type 'Error : System.InvalidCastException' occurred in Microsoft.VisualBasic.dll Additional information: Conversion from string "" to type 'Integer' is not valid. RRS feed

  • Pregunta

  • Buenas aquí les presento este error:


    An unhandled exception of type 'System.InvalidCastException' occurred in Microsoft.VisualBasic.dll

    Additional information: Conversion from string "" to type 'Integer' is not valid.

    Lo que intento hacer con este programa es una alcancía de dolares y centavos.  Creé una función que permite sumar las cantidades entradas.  Por otra parte, el programa debe enviarme un error si lo que escribí en los encasillados no es numero  o está vacio.  Pero me sigue saliendo ese error:

    Código:

    Public Class Form1

        Public Function calcular(ByVal pesetas As Integer, ByVal dimes As Integer, ByVal vellones As Integer, ByVal centavos As Integer) As Double
            Dim total_calcular As Double
            total_calcular = (pesetas * 0.25 + dimes * 0.1 + vellones * 0.05 + centavos * 0.01)

            MsgBox("Usted tiene: " & FormatCurrency(total_calcular, 2),
    MsgBoxStyle.Information)

            Return total_calcular

        End Function
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim pesetas As String
            Dim dimes As String
            Dim vellones As Object
            Dim centavos As Object

            If (pesetas1.Text.Length = 0) Then
                MsgBox("Tiene que llenar la casilla de las pesetas", MsgBoxStyle.Exclamation, )
                pesetas1.Focus()
            End If

            If Not IsNumeric(pesetas1.Text) Then
                pesetas1.Text = ""
                MsgBox("Solo acepta formato en números", MsgBoxStyle.Exclamation, )
            End If

            If (dimes1.Text.Length = 0) Then
                MsgBox("Tiene que llenar la casilla de los dimes", MsgBoxStyle.Exclamation, )
                dimes1.Focus()
            End If

            If Not IsNumeric(dimes1.Text) Then
                dimes1.Text = ""
                MsgBox("Solo acepta formato en números", MsgBoxStyle.Exclamation, )
            End If

            If (vellones1.Text.Length = 0) Then
                MsgBox("Tiene que llenar la casilla de los vellones", MsgBoxStyle.Exclamation, )
                vellones1.Focus()

            End If

            If Not IsNumeric(vellones1.Text) Then
                vellones1.Text = ""
                MsgBox("Solo acepta formato en números", MsgBoxStyle.Exclamation, )
            End If


            If (centavos1.Text.Length = 0) Then
                MsgBox("Tiene que llenar la casilla de los centavos", MsgBoxStyle.Exclamation, )
                centavos1.Focus()
            End If

            If Not IsNumeric(centavos1.Text) Then
                centavos1.Text = ""
                MsgBox("Solo acepta formato en números", MsgBoxStyle.Exclamation, )
            End If


            pesetas = pesetas1.Text
            vellones = vellones1.Text
            dimes = dimes1.Text
            centavos = centavos1.Text
          

            total1.Text = FormatCurrency((calcular(pesetas, dimes, vellones, centavos)), 2)


        End Sub

        
        
    End Class

    domingo, 26 de febrero de 2012 3:12

Respuestas

  • "PandaVega" escribió:

    > Lo que intento hacer con este programa es una alcancía de
    > dolares y centavos.  Creé una función que permite sumar las
    > cantidades entradas.  Por otra parte, el programa debe
    > enviarme un error si lo que escribí en los encasillados no
    > es numero  o está vacio.  Pero me sigue saliendo ese error:
    >

    Hola:

    Te sigue saliendo ese "error", porque si bien verificas si se ha especificado un número en los distintos controles TextBox, NO ABANDONAS EL PROCEDIMIENTO 'Button1_Click' tras mostrar el mensaje de advertencia al usuario, bien mediante la instrucción 'Return', bien mediante la instrucción 'Exit Sub'.

    Al no abandonar el procedimiento, al usuario le aparecerá la advertencia correspondiente, pero el código del procedimiento sigue ejecutándose, y al llegar a la llamada a la función 'calcular'

      total1.Text = FormatCurrency((calcular(pesetas, dimes, vellones, centavos)), 2)
     
    es donde obtienes la excepción que comentas, porque un valor String u Object (que es como tienes declaradas las variables pesetas, dimes, vellones y centavos) con un valor Empty u Nothing respectivamente, no se puede convertir a Integer (que es el tipo de datos de los cuatro parámetros de la función Calcular).

    Como seguramente no tendrás activada la instrucción 'Option Strict', en lugar de obtener la excepción en tiempo de diseño, la obtienes en tiempo de ejecución cuando desees convertir a Integer un valor String (pesetas y dimes) o un valor Object (vellones y centavos).

    Aparte, observo que en la función 'Calcular' efectúas operaciones con decimales utilizando los valores Integer pasados a dicha función. En los tiempos de las pesetas, era difícil que se especificara un valor decimal, no así con los centavos. Los 'dimes' y 'vellones' no he tenido el gusto de conocerlos. :-)

    Si vas a trabajar con valores decimales, lo correcto sería que los parámetros de la función 'Calcular' estuvieran declarados con un tipo de datos de punto flotante (Double o Single), o bien Decimal, y en ésta función, solamente te tienes que preocupar de efectuar la operación correspondiente, sin mostrarle al usuario cuadros de mensaje con el resultado del cálculo. Por ejemplo, la función 'Calcular' bien podría ser la siguiente:

        Public Function Calcular(ByVal pesetas As Double, _
                                 ByVal dimes As Double, _
                                 ByVal vellones As Double, _
                                 ByVal centavos As Double) As Double

            Dim total_calcular As Double = _
                pesetas * 0.25 + dimes * 0.1 + vellones * 0.05 + centavos * 0.01

            Return total_calcular

        End Function

    Y llamarías a dicha función en el evento 'Click' del control llamado 'Button1', de la siguiente manera:

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

            Dim pesetas As Double
            Dim dimes As Double
            Dim vellones As Double
            Dim centavos As Double

            ' Pesetas
            Dim bln As Boolean = Double.TryParse(pesetas1.Text, pesetas)
            If (Not (bln)) Then
                MsgBox("Tiene que llenar la casilla de pesetas con un número.", MsgBoxStyle.Exclamation)
                pesetas1.Focus()
                Return
            End If

            ' Dimes
            bln = Double.TryParse(dimes1.Text, dimes)
            If (Not (bln)) Then
                MsgBox("Tiene que llenar la casilla de dimes con un número.", MsgBoxStyle.Exclamation)
                dimes1.Focus()
                Return
            End If

            ' Vellones
            bln = Double.TryParse(vellones1.Text, vellones)
            If (Not (bln)) Then
                MsgBox("Tiene que llenar la casilla de vellones con un número.", MsgBoxStyle.Exclamation)
                vellones1.Focus()
                Return
            End If

            ' Centavos
            bln = Double.TryParse(centavos1.Text, centavos)
            If (Not (bln)) Then
                MsgBox("Tiene que llenar la casilla de centavos con un número.", MsgBoxStyle.Exclamation)
                centavos1.Focus()
                Return
            End If

            ' Obtenemos el total
            '
            Dim total As Double = Calcular(pesetas, dimes, vellones, centavos)

            total1.Text = String.Format("{0:C2}", total)

            MsgBox("Usted tiene: " & total1.Text, MsgBoxStyle.Information)

        End Sub

    Observa la instrucción 'Return' que se ejecuta cuando no se ha podido convertir a Double el valor del control TextBox correspondiente a una moneda en concreto. Eso hace que el código de ejecución abandone el procedimiento sin más, con lo cual no se ejecutará el restante código existente en el evento Click del control Button1.

    Verás como de ésta manera no obtienes ningún error de conversión cuando el usuario no haya especificado valor alguno en los distintos controles TextBox correspondientes a las monedas.

    Como deseas formatear a moneda el resultado obtenido por la función 'Calcular', para que te aparezca el símbolo monetario actualmente existente en la configuración regional del usuario, en lugar de ejecutar:

        total1.Text = FormatCurrency((calcular(pesetas, dimes, vellones, centavos)), 2)

    Hacemos lo mismo con ésto otro:

        total1.Text = String.Format("{0:C2}", total)

    Es lo mismo, pero digamos que está más orientado a .NET. :-)

    Un saludo


    Enrique Martínez
      [MS MVP - VB]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, activa la instrucción Option Strict.

    • Marcado como respuesta PandaVega martes, 28 de febrero de 2012 3:37
    domingo, 26 de febrero de 2012 8:09
    Moderador

Todas las respuestas

  • hola

    partamos de una base, tienes activa la instrucción Option Strict, solo con esta aseguras que el compilador te marque problemas de tipos de datos que debes solucionar en tu codigo

    veo que haces

    total1.Text = FormatCurrency((calcular(pesetas, dimes, vellones, centavos)), 2)

    pero le pasas por parametro variables que defiens como string y object, eso es pesimo para el codigo

    como puedes declarar

    Public Function calcular(ByVal pesetas As Integer, ByVal dimes As Integer, ByVal vellones As Integer, ByVal centavos As Integer) As Double

    pesetas como integer y luego usar

    Dim pesetas As String

    como string, alli esta el problema, debes convertir los datos al tipo correcto, sino no hay codigo que funcione

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    domingo, 26 de febrero de 2012 3:17
  • "PandaVega" escribió:

    > Lo que intento hacer con este programa es una alcancía de
    > dolares y centavos.  Creé una función que permite sumar las
    > cantidades entradas.  Por otra parte, el programa debe
    > enviarme un error si lo que escribí en los encasillados no
    > es numero  o está vacio.  Pero me sigue saliendo ese error:
    >

    Hola:

    Te sigue saliendo ese "error", porque si bien verificas si se ha especificado un número en los distintos controles TextBox, NO ABANDONAS EL PROCEDIMIENTO 'Button1_Click' tras mostrar el mensaje de advertencia al usuario, bien mediante la instrucción 'Return', bien mediante la instrucción 'Exit Sub'.

    Al no abandonar el procedimiento, al usuario le aparecerá la advertencia correspondiente, pero el código del procedimiento sigue ejecutándose, y al llegar a la llamada a la función 'calcular'

      total1.Text = FormatCurrency((calcular(pesetas, dimes, vellones, centavos)), 2)
     
    es donde obtienes la excepción que comentas, porque un valor String u Object (que es como tienes declaradas las variables pesetas, dimes, vellones y centavos) con un valor Empty u Nothing respectivamente, no se puede convertir a Integer (que es el tipo de datos de los cuatro parámetros de la función Calcular).

    Como seguramente no tendrás activada la instrucción 'Option Strict', en lugar de obtener la excepción en tiempo de diseño, la obtienes en tiempo de ejecución cuando desees convertir a Integer un valor String (pesetas y dimes) o un valor Object (vellones y centavos).

    Aparte, observo que en la función 'Calcular' efectúas operaciones con decimales utilizando los valores Integer pasados a dicha función. En los tiempos de las pesetas, era difícil que se especificara un valor decimal, no así con los centavos. Los 'dimes' y 'vellones' no he tenido el gusto de conocerlos. :-)

    Si vas a trabajar con valores decimales, lo correcto sería que los parámetros de la función 'Calcular' estuvieran declarados con un tipo de datos de punto flotante (Double o Single), o bien Decimal, y en ésta función, solamente te tienes que preocupar de efectuar la operación correspondiente, sin mostrarle al usuario cuadros de mensaje con el resultado del cálculo. Por ejemplo, la función 'Calcular' bien podría ser la siguiente:

        Public Function Calcular(ByVal pesetas As Double, _
                                 ByVal dimes As Double, _
                                 ByVal vellones As Double, _
                                 ByVal centavos As Double) As Double

            Dim total_calcular As Double = _
                pesetas * 0.25 + dimes * 0.1 + vellones * 0.05 + centavos * 0.01

            Return total_calcular

        End Function

    Y llamarías a dicha función en el evento 'Click' del control llamado 'Button1', de la siguiente manera:

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

            Dim pesetas As Double
            Dim dimes As Double
            Dim vellones As Double
            Dim centavos As Double

            ' Pesetas
            Dim bln As Boolean = Double.TryParse(pesetas1.Text, pesetas)
            If (Not (bln)) Then
                MsgBox("Tiene que llenar la casilla de pesetas con un número.", MsgBoxStyle.Exclamation)
                pesetas1.Focus()
                Return
            End If

            ' Dimes
            bln = Double.TryParse(dimes1.Text, dimes)
            If (Not (bln)) Then
                MsgBox("Tiene que llenar la casilla de dimes con un número.", MsgBoxStyle.Exclamation)
                dimes1.Focus()
                Return
            End If

            ' Vellones
            bln = Double.TryParse(vellones1.Text, vellones)
            If (Not (bln)) Then
                MsgBox("Tiene que llenar la casilla de vellones con un número.", MsgBoxStyle.Exclamation)
                vellones1.Focus()
                Return
            End If

            ' Centavos
            bln = Double.TryParse(centavos1.Text, centavos)
            If (Not (bln)) Then
                MsgBox("Tiene que llenar la casilla de centavos con un número.", MsgBoxStyle.Exclamation)
                centavos1.Focus()
                Return
            End If

            ' Obtenemos el total
            '
            Dim total As Double = Calcular(pesetas, dimes, vellones, centavos)

            total1.Text = String.Format("{0:C2}", total)

            MsgBox("Usted tiene: " & total1.Text, MsgBoxStyle.Information)

        End Sub

    Observa la instrucción 'Return' que se ejecuta cuando no se ha podido convertir a Double el valor del control TextBox correspondiente a una moneda en concreto. Eso hace que el código de ejecución abandone el procedimiento sin más, con lo cual no se ejecutará el restante código existente en el evento Click del control Button1.

    Verás como de ésta manera no obtienes ningún error de conversión cuando el usuario no haya especificado valor alguno en los distintos controles TextBox correspondientes a las monedas.

    Como deseas formatear a moneda el resultado obtenido por la función 'Calcular', para que te aparezca el símbolo monetario actualmente existente en la configuración regional del usuario, en lugar de ejecutar:

        total1.Text = FormatCurrency((calcular(pesetas, dimes, vellones, centavos)), 2)

    Hacemos lo mismo con ésto otro:

        total1.Text = String.Format("{0:C2}", total)

    Es lo mismo, pero digamos que está más orientado a .NET. :-)

    Un saludo


    Enrique Martínez
      [MS MVP - VB]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, activa la instrucción Option Strict.

    • Marcado como respuesta PandaVega martes, 28 de febrero de 2012 3:37
    domingo, 26 de febrero de 2012 8:09
    Moderador