none
ayuda, problema con decimales

    Pregunta

  • Hola,

    mi problema es el siguiente, tengo un textbox donde me introducen un importe, dicho importe pueden ponerlo con decimales o no. Yo lo paso a decimal y lo guardo en una BBDD sql server. Pues si yo incluyo el valor con dos decimales, p.ej. 12345.67 en la bbdd se me guarda 1234567.00

    ¿qué solución le puedo dar a este problema? llevo un buen rato buscando y no encuentro una solución satisfactoria.

    jueves, 14 de julio de 2011 7:36

Respuestas

  • Hola Sergio:

     

    Por lo que he visto en la documentacion de Maskededit en esta

    url http://www.asp.net/ajax/ajaxcontroltoolkit/Samples/MaskedEdit/MaskedEdit.aspx

    el separador decimal es el ".".

     

    Sergio, no tengo posibilidad de probarlo con la ajaxControltoolkit, pero te he hecho una prueba con Winforms que a la postre se va a comportar igual con MaskedTextBox y la mascara la he definido como tu "999999999.99".

     Para realizar el cast correcto dejalo como lo tenías al principio  Convert.ToDecimal(textbox1.text); yo lo he probado y funciona. 

     

    Lo de cambiar el punto por la coma no te lo recomiendo, puesto que tendrías que hacerlo a nivel Javascript y yo lo hice hace ya algún tiempo con esa librería y no es nada facil, si pudiera pasarte el código que no lo tengo lo haría sin problema :).

     

    De todas formas sino te funciona lo mas sencillo sería hacer un replace textbox1.text.Replace(",",".");

     

    Saludos,

     



    phurtado
    jueves, 14 de julio de 2011 11:02

Todas las respuestas

  • Hola Sergio:

    Como tienes definido el campo de la BB.DD. Lo puedes pasar.

     


    phurtado
    jueves, 14 de julio de 2011 8:37
  • Hola Pedro,

    perdón, se me ha pasado indicarlo.

    decimal(18,2)

     

    Es para un importe en euros


    jueves, 14 de julio de 2011 8:45
  • Hola Sergio:

    La columna la tienes preparada para poder almacenar decimales. El problema lo tienes en el cliente. Y pueden ser varias cosas

    1. Los parametros que envias a la BB.DD. no lo tienes definido correctamente.

    2. El cast que realizas en el cliente para transformar el texto a decimal es incorrecto.

     

    Pasa el codigo cliente y vemos como te podemos ayudar.

     

    Saludos.


    phurtado
    jueves, 14 de julio de 2011 8:52
  • Vamos a ello.

    En el textbox me pueden introducir valores del tipo:

    1234

    1234.25

    (Estoy mirando de usar el MaskEdit para que solo me puedan poner el punto decimal y no la coma)

     

    En la base de datos se ha de guardar respectivamente:

    1234.00

    1234.25

     

    La asignación la realizo de la siguiente manera:

    objeto.Campodecimal = Convert.ToDecimal(textbox1.text);

     

    objeto.Campodecimal está definido como:

    private decimal m_Campodecimal = 0;

    public decimal Campodecimal {

       get {return m_Campodecimal; } {set m_Campodecimal = value; }

    }

     

    La asignación del valor a parámetro para pasarlo a la Stored Procedure lo hago así:

    miCommand.Parameters.Add("@Valor", System.Data.SqlDbType.Decimal, 18).Value = objeto.Campodecimal;

     

    jueves, 14 de julio de 2011 9:01
  • Hola Sergio:

     

    Observo dos problemas:

     

    1. Lo que tu apuntas el punto y la coma cambia tu sentencia 

     

    Convert.ToDecimal(textbox1.text); por Convert.ToDecimal(textBox1.Text,System.Globalization.CultureInfo.InvariantCulture);

    Si quieres utilizar el punto de lo contrario siempre tendrás que utilizar la coma.

     

    2. El parametro que construyes cambia tu instruccion por esto:

     

    System.Data.SqlClient.SqlParameter p = new System.Data.SqlClient.SqlParameter("@valor", SqlDbType.Decimal, 9);
    
          p.Precision = 18;
    
          p.Scale = 2;
    
    miCommand.Parameters(p);
    

    Saludos.


    phurtado
    jueves, 14 de julio de 2011 9:20
  • Hola Pedro,

    la parte del parámetro ahora funciona correctamente, sin embargo tengo un problema con la máscara. Tengo un MaskEditExtender definido de la siguiente manera, pero al entrar en el campo, la máscara que me obliga a utilizar muestra una coma (y si es coma no me funciona el código), y no consigo que sea un punto.

    ¿Puedes ayudarme con esto?

     

    <ajaxToolkit:MaskedEditExtender ID="MaskedEditExtender2" runat="server"

    TargetControlID="TextBox1"

                Mask="999999999.99"

                MessageValidatorTip="true"

                OnFocusCssClass="MaskedEditFocus"

                OnInvalidCssClass="MaskedEditError"

                MaskType="Number"

                InputDirection="RightToLeft"

                AcceptNegative="Left"

                DisplayMoney="Right"

                ErrorTooltipEnabled="True"

    jueves, 14 de julio de 2011 10:33
  • Hola Sergio:

     

    Por lo que he visto en la documentacion de Maskededit en esta

    url http://www.asp.net/ajax/ajaxcontroltoolkit/Samples/MaskedEdit/MaskedEdit.aspx

    el separador decimal es el ".".

     

    Sergio, no tengo posibilidad de probarlo con la ajaxControltoolkit, pero te he hecho una prueba con Winforms que a la postre se va a comportar igual con MaskedTextBox y la mascara la he definido como tu "999999999.99".

     Para realizar el cast correcto dejalo como lo tenías al principio  Convert.ToDecimal(textbox1.text); yo lo he probado y funciona. 

     

    Lo de cambiar el punto por la coma no te lo recomiendo, puesto que tendrías que hacerlo a nivel Javascript y yo lo hice hace ya algún tiempo con esa librería y no es nada facil, si pudiera pasarte el código que no lo tengo lo haría sin problema :).

     

    De todas formas sino te funciona lo mas sencillo sería hacer un replace textbox1.text.Replace(",",".");

     

    Saludos,

     



    phurtado
    jueves, 14 de julio de 2011 11:02
  • hola

    cono envias en la query este valor con decimales, usas parametros

    adema que cultura estas suando en tu aplicacion, veo que defiens el punto como separador de decimales, entocnes la cultura es en-US ?

    porque si por ejemplo es es-ES tendras problemas para convertir porque aqui el separador es la coma

     

    prueba de definir una cultura unica para tu aplicacion

     

    Cómo: Establecer referencia cultural actual mediante programación en una aplicación de ASP.NET

     

    y luego usa parametros convirtiendo de decimal

     

    using (SqlConnection conn = new SqlConnection("connection string")) {
        conn.Open();

        string sql = "INSERT INTO NombreTabla (campo) VALUES (@param)";
        SqlCommand cmd = new SqlCommand(sql, conn);


         cmd.Parameters.AddWithValue("@param", Convert.ToDecimal(TextBox1.Text));

         cmd.ExecuteNonQuery();

       

    }

     

    si la cultura es es-US tomara correctamente el punto como decimal cuando convierta del textbox

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    jueves, 14 de julio de 2011 11:50
  • Hola:

     

    Te paso unas lineas de codigo donde puedes comprobar que Convert falla

     

          Decimal d = Convert.ToDecimal("12.25"); //Falla

        d = Convert.ToDecimal("12.25", CultureInfo.InvariantCulture); //Ok.

        //Cambiar de Cultura

                System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("EN-US");

                d = Convert.ToDecimal("12.25"); //Ok.

                d = Convert.ToDecimal("12,25"); //Falla

    Esto te puede ayudar para que veas claro lo que comenta Leandro.

    Saludos,


    phurtado
    jueves, 14 de julio de 2011 12:41
  • Hola,

    gracias a ambos por la ayuda.

    Pedro, como tu dices funciona correctamente :) en cuanto a lo del MaskEdit, si veo que no me acaba de convencer, intentaré probar con otra cosa, tal vez un RegulaExpressionValidator

    Leandro, la aplicación tiene varios idiomas, por eso que me gustaría que soportara ambos separadores de decimales (punto y coma), pero si no puede ser, tal vez sería mejor decantarse por el punto, ya que para introducir cantidades desde el teclado numérico es más cómodo que ir a buscar la coma.

    jueves, 14 de julio de 2011 12:42
  • la aplicación tiene varios idiomas, por eso que me gustaría que soportara ambos separadores de decimales (punto y coma), pero si no puede ser, tal vez sería mejor decantarse por el punto

    claro pero el tema es que el usuario debe conocer que cultura esta aplciada en ese momento he ingresar los decimales de la forma que corresponde para esa cultura

    o se asi la cultura es en-US puedeo sua rel punto como decimal

    pero si es es-ES debe usa la coma

    pero esto debe respetarlo el usuario para que funcione, si al tener la cultura es-ES pone un punto obtendras el problema que se presenta ahora cuando intentente conviertir de string a decimal

     

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    jueves, 14 de julio de 2011 12:49
  • Hola Sergio:

     

    Si la aplicación funciona con varios idiomas lo de conformarse con lo del punto no me parece una buena idea :). ¿Por que no intentas parametrizar el parametro  Mask="999999999.99" en funcion de la cultura.

    Aunque te repito que yo sufri de lo lindo hace algunos años con el MaskEdit de la control ToolKit. No te puedo decir si actualmente soporta Globalizacion, hace algunos años no.

     

    Pero insisto dale al usuario lo que quiere no lo que te sea más facil :)

     

    Saludos.


    phurtado
    jueves, 14 de julio de 2011 12:51
  • Hola Pedro,

    estoy probando con otra cosa, como decía antes un RegulaExpressionValidator, casi lo tengo :)

    He encontrado en otro post esta expresión ([\+|-]{0,1})([0-9]{1,10})[[.|,]([0-9]{1,2})]{0,1} que casi casi me sirve a la perfección, el problema es que si pones una cantidad sin decimales te salta el validador, y en mi caso, debería soportarlo también, ya que al hacer el insert en la bbdd si no se informan se pone .00 por defecto.

    El problema es que esto de las expresiones regulares no lo domino ;p 

    jueves, 14 de julio de 2011 13:03
  • Hola,

    lo primero gracias por vuestra ayuda, creo que he encontrado la forma de hacerlo.

    por un lado uso un RegularExpressionValidator, la expresión regular que me funciona para que tome números decimales o no y dos decimales en el caso de usarlos es: ([\+|-]{0,1})([0-9]{1,10})|[[.|,]([0-9]{1,2})]{0,1}

    Después a la hora de asignar a la variable el contenido del campo, dejo el convert a pelo y hago un replace en el texto del textbox de punto por coma y listos, así pueden usar el separador que quieran indistintamente de la cultura, y también fuerzo una estructura fija para introducir los importes.

    También incluyo aquí este link sobre expresiones regulares que me ha resultado muy util (y eso que no lo he podido leer entero)

    http://www.php-hispano.net/archivos/Manuales/212/1/Manual-de-Expresiones-Regulares1.html

     

    jueves, 14 de julio de 2011 13:28
  • Hola Sergio:

    Con las expresiones regulares estoy como tu:) pero a lo que no le veo problema es que en la BBDD este grabado .00 

    ¿Esto te da error? Si no te da error el valor para esa fila en esa columna es 0.

     

    Saludos.


    phurtado
    jueves, 14 de julio de 2011 13:32
  • Hola Pedro,

    no me da error, de hecho es lo que pretendía, que siempre informe dos decimales, tanto si los pongo como si no.

    Aunque he cantado victoria muy pronto, la expresión me funciona bien en el validador que tu me has pasado, pero luego en la aplicación no me va. No me deja incluir valores sin decimales.

    Ahora abriré un nuevo post, por si alguien me puede ayudar con ella.

     

    jueves, 14 de julio de 2011 14:03