none
Problemas con campo decimal de tabla access RRS feed

  • Pregunta

  • Hola, Tengo problemas para insertar un numero decimal en una tabla de una db-access.
    El campo esta definido en la db como Decimal.
    En la configuración reiginal está establecida la coma (,) como separador decimal y el punto (.) como separador de miles. Ej: 1.235,45 = 1235 con 45 centesimos.

    Con ésta configuración de idioma, c# convierte un numero a Decimal así:

     Decimal.Parse("2535.31") --> 253531
     Decimal.Parse("2535,31") --> 2535.31

    El problema esta en que cuando guardo en la db con un command con parametros, se guarda como numero entero.
    Aqui pongo parte del código:

         .......
         Decimal Imp = Decimal.Parse(txtImpOCM.Text);
        ......

         int r = ng.guardarCambiosOrdensDeCompra(IdTipo, IdProv, Nro, Fecha, Imp, Obs, id);
         

    Aquí está el procedimiento "ng.guardarCambiosOrdensDeCompra"

        public int guardarOrdenDeCompra(Int16 IdTipo, Int16 IdProv, String Nro, DateTime Fecha, decimal Imp, String    Obs)
        {
          String sql = "INSERT INTO OrdenCompra (Tipo, Proveedor, Nro, Fecha, Importe, Obs) Values (?, ?, ?, ?, ?, ?)";
         
          OleDbCommand cmd = new OleDbCommand(sql, this._cnn);
          ...
            cmd.Parameters.Add("", OleDbType.Decimal).Value = Imp;
          ...
          
            return (int)cmd.ExecuteNonQuery();
        }

    Esto funciona, es decir inserta el nuevo registro, pero con el valor entero en el campo Importe:
    yo le paso:  "2535,31"
    y se guarda: 253531

    como se resuelve esto sin tener que cambiar la configuración de idioma en el paner de control de windows.

    Muchas gracias desde ya. Saludos

    viernes, 23 de octubre de 2009 13:25

Respuestas

  • "AntiWork" escribió:

    > por mas que le pase un número con coma (o que convietra la coma en punto),
    > al final "Parse" vuelve a ponerle el punto.

    ¡Pues llevás más razón que un santo!

    Aparte de lo que te he comentado anteriormente, en lugar de definir el parámetro como Decimal, haz una prueba definiéndolo como Varchar:

        cmd.Parameters.Add("", OleDbType.VarChar).Value = Imp;

    Se entiende que en la tabla de la base de Access, el campo Decimal tienes al menos una escala de 2.

    Si ves que definiendo el parámetro con el tipo VarChar funciona bien, en lugar de definir el parámetro Imp con el tipo Decimal, defínelo con el tipo string, de ésta manera evitas tener que utilizar el método Parse.


    Enrique Martínez [MS MVP - VB]
    • Marcado como respuesta AntiWork viernes, 23 de octubre de 2009 15:57
    viernes, 23 de octubre de 2009 15:31

Todas las respuestas

  • "AntiWork" preguntó:

    > como se resuelve esto sin tener que cambiar la configuración de idioma en el paner de control de windows.

    Hola:

    El problema no lo tienes con el campo decimal de la tabla de Access. El problema lo tienes porque insertas un punto en el valor del control TextBox, cuando lo que tienes que insertar es una coma para que el método Parse te convierta el valor a Decimal, tal y como tu mismo has podido comprobar.

    Antes de llamar al método Parse de la estructura Decimal, reemplaza el posible punto por la coma decimal:

                // Reemplazamos el punto por la coma
                string temp = txtImpOCM.Text.Replace('.', ',');
    
                Decimal Imp = Decimal.Parse(temp);
    
                int r = ng.guardarCambiosOrdensDeCompra(IdTipo, IdProv, Nro, Fecha, Imp, Obs, id);
    


    Un saludo

    Enrique Martínez [MS MVP - VB]
    viernes, 23 de octubre de 2009 13:55
  • Hola, Gracias por tu pronta respuesta.
    Eso ya lo hice. Probé de la dos mantera: cambie (.) por (,) primero  y despues hice al reves.
    Yo observé lo siguente:
    si                 txt == "2535,31"
    entonces      Decimal.Parse(txt)==2535.31

    por lo tanto, por mas que le pase un número con coma (o que convietra la coma en punto), al final "Parse" vuelve a ponerle el punto.

    saludos



    viernes, 23 de octubre de 2009 14:21
  • hola

    Double.Parse

    has probado como muestra este link, de usar la cultura especificamente en ese parseo, o sea no cambiar la cultura general de toda tu aplicacion

    CultureInfo culture = new CultureInfo("en-US");
    Double number = Double.Parse(Imp, culture.NumberFormat);



    y luego si usarlo:

    cmd.Parameters.Add("", OleDbType.Decimal).Value = number ;


    saludos
    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    viernes, 23 de octubre de 2009 14:44
  • "AntiWork" escribió:

    > por mas que le pase un número con coma (o que convietra la coma en punto),
    > al final "Parse" vuelve a ponerle el punto.

    ¡Pues llevás más razón que un santo!

    Aparte de lo que te he comentado anteriormente, en lugar de definir el parámetro como Decimal, haz una prueba definiéndolo como Varchar:

        cmd.Parameters.Add("", OleDbType.VarChar).Value = Imp;

    Se entiende que en la tabla de la base de Access, el campo Decimal tienes al menos una escala de 2.

    Si ves que definiendo el parámetro con el tipo VarChar funciona bien, en lugar de definir el parámetro Imp con el tipo Decimal, defínelo con el tipo string, de ésta manera evitas tener que utilizar el método Parse.


    Enrique Martínez [MS MVP - VB]
    • Marcado como respuesta AntiWork viernes, 23 de octubre de 2009 15:57
    viernes, 23 de octubre de 2009 15:31
  • Hola- Gracias por sus respuestas

    El Problema era la escala que estaba en 0.

    Muchas gacias
    viernes, 23 de octubre de 2009 15:54
  • "AntiWork" escribió:

    > Primero definí el parametro como varchar. Y me trunca el numero
    > ( solo guarda la parte entera). Entonces probé cambiando también
    > la variable Imp al tipo String y el resultado es el mismo.

    No puedo reproducir lo que me estás comentando. Si en el control TextBox existe el número 125.36, ese será el número que se guardará en la tabla de la base de Access, teniendo definido como string el parámetro Imp, y como VarChar el parámetro del comando.

    Se supone que primero has reemplazado el punto por la coma, tal y como te comenté en mi primer mensaje. Con una configuración regional de español, al parámetro le tiene que llegar el número con la coma decimal.



    Enrique Martínez [MS MVP - VB]
    viernes, 23 de octubre de 2009 16:04
  • "AntiWork" escribió:

    > El Problema era la escala que estaba en 0.

    ¡Jeje! Mira que te indiqué que entendía que en la tabla de la base de Access, el campo Decimal tiene al menos una escala de 2. :-))



    Enrique Martínez [MS MVP - VB]
    viernes, 23 de octubre de 2009 16:08
  • Igualmente no entiendo por que al parámetro hay que definirlo como VarChar. ¿es que los tipos decimal de Access y .Net no son compatibles?
    viernes, 23 de octubre de 2009 16:16
  • "AntiWork" preguntó:

    > Igualmente no entiendo por que al parámetro hay que definirlo como VarChar.
    > ¿es que los tipos decimal de Access y .Net no son compatibles?

    El problema está en la configuración regional de tu sistema operativo. Si en tu sistema tuvieras una configuración de inglés americano, observarías que no tendrías ningún problema con el tipo de dato Decimal, de hecho, si deseas hacer una prueba, selecciona desde el Panel de Control una configuración regional de inglés de Estados Unidos y verás como el propio Microsoft Access te acepta todos los números decimales escritos con un punto decimal, y te tomará como enteros aquellos que le hayas especificado una coma decimal. Es decir, al revés de lo que sucede con una configuración regional de español de España.

    Para no tener problemas con la configuración regional, es por lo que te he indicado que utilizaras como parámetro un valor VarChar, y será el propio motor Microsoft Jet o Microsoft ACE el que se encargará de formatearlo a un valor Decimal válido.

    Ten en cuenta que el lenguaje SQL se lo inventaron los americanos, y lo desarrollaron utilizando sus costumbres propias de separar con un punto los decimales de un número.

    Otro tanto de lo mismo suele suceder con las fechas, donde Access utiliza el formato americano de mes/día/año, aunque tu visualices las fechas desde el propio entorno de Microsoft Access en formato español, pero para que Access lo tome como una fecha correcta, tienes que insertar la fecha con el formato americano. Con el uno de enero de cada año, no habrá problema alguno, pero ¿qué sucederá si ejecutas una consulta SQL para insertar la fecha del dos de enero en formato español? Qué Microsoft Access te lo tomará como el uno de febrero. ¡Así de claro! :-)

     


    Enrique Martínez [MS MVP - VB]
    sábado, 24 de octubre de 2009 9:59
  • Muchas gracias. Clarisima tu respuesta.

    Saludos
    sábado, 24 de octubre de 2009 13:44