Problema con formatos VB.NET 2010, Access 2007[SOLUCIONADO]

Iniciado por Yaldabaot, 27 Julio 2014, 19:48 PM

0 Miembros y 1 Visitante están viendo este tema.

Yaldabaot

Hola,

Hice una aplicación de control de una serie de datos, la aplicación hasta el momento iba bien, pero cuando me empezaron a acosar unos usuarios con extrañas exepciones que en mi vida nunca ha visto.

La aplicación ya tenía una cierta cantidad de tiempo, y en los otros ordenadores pues funciona a la maravilla, hasta yo mismo verifiqué que al insertarse los valores sean los correctos.

Lo único y estoy casi seguro que el problema radica en este dato:

Cuando el usuario escribe en su caja de texto y pone por ejemplo un valor numérico 70000, cuando pierde el foco el text box formatea la variable que recibe  quedando de esta manera : 70,000 , a modo de código pues el valor es este : Double monto =  txtmonto.toString("###,###,###")

Cuando se inserta en la base de datos simplemente se inserta con el separador de miles, hasta el momento que tiene la aplicación tiene más de un año casi y hasta ahora cero problemas. El campo den la base de datos tiene un valor de double, en este caso el motor de base de datos es Acess 2007.


Cuando revisé en el sistema operativo Windows 7, tenía que los separadores de miles eran con "," y los decimales con "."

Cuando el usuario acosador inserta le aparece esta imagen:




Cabe decir, que al formato del monto que es double lo pase luego a string para resolver el problema y hacerle un .replace(",",nothing) para que el número llegue intacto a la tabla, funciona en otros ordenadores y en ese bendito ordenador no -.-.

Y es un usuario muy hostigador y molesto, ojala puedan ayudarme con la ayuda.

Disculpen las molestias por la imagen, no se subirla bien a un foro

Les agradezco la ayuda brindada, y desde ya muchas gracias.
Nunca me contestan -_-

Yaldabaot

Nadie sabe??, les agradecería alguna idea o ayuda!.
Nunca me contestan -_-

Yaldabaot

#2
Les daré el fragmento del código a ver si alguien sabe

Código (vbnet) [Seleccionar]


Dim comprobar As String
       Dim monto As Double

       comprobar = TxtMonto.Text

       If IsNumeric(comprobar) <> True Then
           lblMonto.ForeColor = Color.Red
           lblMonto.Text = "Dato Incorrecto"
           btnGuardarDatos.Enabled = False
       Else
           btnGuardarDatos.Enabled = True
           lblMonto.Text = ""

           'Actualización
           monto = CDbl(comprobar)
           TxtMonto.Text = monto.ToString("###,###,###.##")

       End If



Y acá pues es donde lo inserta

Código (vbnet) [Seleccionar]


   monto = CDbl(TxtMonto.Text)
   cmd = New OleDb.OleDbCommand("insert into xxx1(xxx)  values  ('" & monto & "')" , conn)


Nunca me contestan -_-

Yaldabaot

La excepción que tira antes de la imagen(tree view sin abrir) dice lo siguiente:

La conversión de la cadena "La operación de usar una consu" en el tipo "Integer" no es válida.

Lo pongo examente como viene el enunciando para ver si me ayudan, porque sinceramente este error no se que es, es absurdo.

GRACIAS POR LEERME
Nunca me contestan -_-

Eleкtro

#4
1) El mensaje de la excepción es bien claro, no se puede tratar la cadena de texto "La operación necesita una consu" como si fuese un valor de tipo Integer, en alguna parte del código, la cual no tiene porque ser necesariamente la que has mostrado, estás intentando hacer ese tipo de conversión, y es donde está el error.
Aunque te parezca un error absurdo, es muy común en los inicios de cualquier programador equivocarse de esa manera.

2) En el código que has mostrado parece como si, mientras un usuario escribe en un textbox, tu quisieras comprobar si lo que escribe es un número, y luego reemplazar/formatear el texto de ese textbox mientras el usuario pueda seguir escribiendo?... en ese caso debes darle otro enfoque a lo que intentes conseguir.

3) En lugar de usar métodos del siglo pasado de VisualBasic6 (IsNumeric) deberías reemplazarlo por métodos de la programación actual (Double.TryParse), ejemplo:

Código (vbnet) [Seleccionar]
       Dim comprobar As String = TxtMonto.Text
       Dim monto As Double = 0.0R
       Dim Success As Boolean = Double.TryParse(comprobar, monto)

       Select Case Success
           Case True
               lblmonto.Text = ""
               TxtMonto.Text = monto.ToString("###,###,###.##")

           Case Else
               lblmonto.ForeColor = Color.Red
               lblmonto.Text = "Dato Incorrecto"

       End Select

       btnGuardarDatos.Enabled = Success


4) Si lo que pretendes es que en el TextBox solo se puedan escribir dígitos y puntos, como ya digo tienes que darle otro enfoque al código, esa no es la manera apropiada, esta sería una manera:

Código (vbnet) [Seleccionar]
   ''' <summary>
   ''' The keys that are allowed to press in the TextBox.
   ''' </summary>
   Private ReadOnly AllowedKeys As Char() = "0123456789."

   ''' <summary>
   ''' Handles the Enter event of the TextBox control.
   ''' </summary>
   ''' <param name="sender">The source of the event.</param>
   ''' <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
   Private Sub TxtMonto_Enter(ByVal sender As Object, ByVal e As EventArgs) Handles TxtMonto.MouseEnter

       ' Disable Copy/Paste contextmenu by creating a new empty one.
       If sender.ContextMenuStrip Is Nothing Then
           sender.ContextMenuStrip = New ContextMenuStrip
       End If

   End Sub

   ''' <summary>
   ''' Handles the KeyPress event of the TextBox control.
   ''' </summary>
   ''' <param name="sender">The source of the event.</param>
   ''' <param name="e">The <see cref="KeyPressEventArgs"/> instance containing the event data.</param>
   Private Sub TxtMonto_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) Handles TxtMonto.KeyPress

       Select Case e.KeyChar

           Case Convert.ToChar(Keys.Enter) ' 'Enter' key is pressed.
               ' Do something here...

           Case Convert.ToChar(Keys.Back) ' 'Backspace' key is pressed.
               e.Handled = False ' Delete the character

           Case Convert.ToChar(Keys.Capital Or Keys.RButton) ' 'CTRL+V' combination is pressed.
               ' Paste clipboard content only if contains allowed keys.
               e.Handled = Not Clipboard.GetText().All(Function(c) AllowedKeys.Contains(c))

           Case Else ' Other key is pressed.
               e.Handled = Not AllowedKeys.Contains(e.KeyChar)

       End Select

   End Sub


Otra manera sería que en lugar de usar un TextBox normal utilizases un MaskedTextbox y aplicarle una máscara numérica, usando la propiedad "Mask".

De todas formas no me ha quedado muy claro lo que pretendes conseguir, la función de ese textbox y porque intentas aplicarle un formato específico mientras el usuario typea.

5) Si tienes dudas acerca dle formato que le estás intentando dar al número, tienes información y ejemplos en MSDN:
· Double.ToString(IFormatProvider)
· Double.ToString(String)

Saludos








Yaldabaot

Gracias por la respuesta, voy a verificar el asunto. Al fin alguien me ha dado la luz en el problema, todos me decían que era sencillo pero no me especificaban cómo arreglarlo, pues lo único que veía era el error del parse, el cuál se como resolverlo pero jamás me imaginé que era eso.

Ahora bien,¿ cómo hago yo para saber dónde está el error, si la aplicación no está donde tengo el IDE, lo que ves es lo que me lanza?.

Pues no tengo muchos años de programar, llevo pocos, aveces pues uno va aprendiendo poco a poco, y agradezco mucho que personas que sepan más que yo me indiquen como mejorarlo y hacerlo de la manera correcta.

Gracias Elektro, te informaré cuando lo resuelva y cómo lo hice.

Nunca me contestan -_-

Eleкtro

#6
Cita de: Yaldabaot en  6 Agosto 2014, 22:34 PMAhora bien,¿ cómo hago yo para saber dónde está el error, si la aplicación no está donde tengo el IDE, lo que ves es lo que me lanza?.

Pues a menos que el Client se instale VS y sepa depurar y utilizar los breakpoints y comprobar los autos y etc... no se me ocurre como saberlo desde el lado del Server xD.

Creo que lo más lógico dado el caso sería que añadieses controles de errores (bloques de Try/Catch) en las partes del código que tu creas que puedan ser conflictivas, y al detectar la excepción mostrases un msgbox con todos los datos, como el método que lanzó el error y los valores que habia introducido al momento de la excepción, y el usuario no tendría más que copiar el texto de ese MsgBox para reportarte el problema, supongo que eso te ayudaría a estar mucho más cerca o resolver completamente el supuesto Bug.

Aquí tienes todo lo necesario para saber como mostrar los datos en el MsgBox:
· Exception Properties
( Las propiedades que deberías mostrar en mi opinión: Message, TargetSite, Source y StackTrace además de 'txtmonto.text' y en fin lo que tu consideres oportuno )

En fin, deberías hacer eso, optimizar los chequeos de tu App y cuando lo hayas echo pasarle la actualización del programa a ese Client ...y ya solo quedaría esperar a que diese error y te lo reportase.

Quizás esto también te pueda servir de algo en el asunto: [SOURCE] Elektro ErrorDialog aunque para mostrar el método desencadenante habría que hacerle algún retoque.

Un saludo




Reectifico, no me habia dado cuenta hasta ahora que la excepción de la imagen es de tipo Integer, no Double, por ende estás comprobando el bloque de código incorrecto.
lo más lógico sería antes de nada (antes de ponerte a hacer 1.000 chequeos de errores), comprobar las conversiones que haces en el código, es decir todas las conversiones de String a Integer (Cint(), Integer.tryparse, convert.toint32() etc... no se como lo estarás haciendo), una de ellas es la conflictiva, revisa eso.

Saludos








Yaldabaot

Gracias elektro por la atención, voy a verificarlo, te cuento como me va!.
Nunca me contestan -_-

Yaldabaot

 Dim count As Integer = Convert.ToInt32(cmd.ExecuteScalar())

Esa es la única rara, será esa?.
Nunca me contestan -_-

Eleкtro

Cita de: Yaldabaot en  6 Agosto 2014, 23:33 PM
Dim count As Integer = Convert.ToInt32(cmd.ExecuteScalar())

Esa es la única rara, será esa?.

pues... sin probarlo no puedo decírtelo yo.

asegúrate de que el output que recibes de la cmd es númerico...

saludos.