Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Problemas con Base de Datos Access y cálculos con decimales (https://www.clubdelphi.com/foros/showthread.php?t=67131)

ricardo_soria 30-03-2010 21:24:53

Problemas con Base de Datos Access y cálculos con decimales
 
Estimados Amigos,

Agradeceré mucho a quien me pueda orientar sobre la forma de resolver este problema con conexión a bases de datos...

Me conecto a una base de datos sencilla en Access, a través de un componente ADOConnection (no uso nada de ODBC ni otras cosas). Me conecto a una tabla a través de de un ADOTable, luego conecto a esta mediante un DataSource, y finalmente, despliego los datos de la tabla en un DBGrid. Hasta aquí todo bien. El problema viene debido a que en la tabla existe un campo 'valor' en donde deben guardarse cantidades monetarias. Originalmente en la base de datos este campo era de tipo 'Moneda', y en mi aplicación en Delphi debo hacer cierto cálculo para establecer el valor que debe guardarse en este campo, lo que hago de la siguiente manera:

Código:

ADOTable1.FieldValues['valor']:=Ceil(minutos(FieldValues['inicio'], FieldValues['fin'])/6)*0.1;
La función 'minutos' devuelve un resultado integer. Este valor se divide para 6, y se aplica la función Ceil, cuyo resultado sigue siendo integer. Finalmente, se multiplica este valor por 0.1, con lo cual ya pasa a ser decimal. Pero en el momento en que se realiza el Post, en el DBGrid aparece "BCD Overflow" en lugar del valor calculado que debería aparecer. Curiosamente, en la base de datos si se guarda el valor calculado. Pero en el DBGrid en mi aplicación, siempre sigue apareciendo el "BCD Overflow". Incluso en tiempo de diseño, se puede ver el valor correcto en el DBGrid, pero al ejecutar la aplicación no.

He buscado mucho sobre este problema, pero no he encontrado nada que realmente me haya ayudado a resolverlo. He probado cambiando el campo en la Base de datos de 'Moneda' a 'Número', de tipo 'Simple', con 2 lugares decimales (en Access), en cuyo caso, se almacena por ejemplo el valor 0.100000001490116, cuando lo correcto sería simplemente 0.10, no tengo idea por qué se altera ese valor, y lógicamente, necesito que se guarde el valor exacto. Además, por compatibilidad con versiones anteriores de esta Base de datos, preferiría enfáticamente que el campo siga siendo tipo 'Moneda'.

De antemano, muchas gracias por tomarse la molestia de leer todo este detalle del problema, y quedaré muy agradecido por sus respuestas.

Saludos,

Caral 30-03-2010 21:40:23

Hola
Yo usaría un campo numérico (double) en access, esto es suficiente.
La diferencia entre moneda y numérico es nula ya que cualquiera de los dos en formateable.
Para recibir los datos se puede de muchas formas.
Saludos

ricardo_soria 31-03-2010 02:58:57

Cita:

Empezado por Caral (Mensaje 358871)
Hola
Yo usaría un campo numérico (double) en access, esto es suficiente.
La diferencia entre moneda y numérico es nula ya que cualquiera de los dos en formateable.
Para recibir los datos se puede de muchas formas.
Saludos

Hola Caral:

Muchas gracias por tu respuesta!!!

En efecto, configurando el campo en Access como Númerico/Double se ha solucionado el problema, y ya puedo ver el valor exacto (0.10 por ejemplo) en el DBGrid. Ahora, solo por curiosidad, no comprendo bien tus comentarios adicionales; tu dices que no hay diferencia entre moneda y numérico, significa esto que el campo podría después de todo quedarse como moneda?? Además, dices que "se puede recibir los datos de muchas formas", me lo podrías tal vez ilustrar un poco más??

De antemano, muchas gracias.

Saludos,

mcs 31-03-2010 08:20:24

Yo diría que en Access el campo Moneda y el double son diferentes. Por norma general yo trabajaría con Moneda, ya que es un campo BCD, mientras que el double es coma flotante.

Que ventajas tenemos con un BCD? Pues que los valores que asignamos a aquél campo son exactos (10,23 es esto, 10,23). Por el contrario, en un campo float o double hay valores no representables (por ej, 10,23 nos podría quedar cómo 10,2987879), cosa que puede provocar graves problemas de cálculo, lo cual no es nada interesante cuando estamos trabajando en valores monetarios (tuve bastantes problemas en Java por este motivo, hasta que descubrí que debía usar variables del tipo BigDecimal y no del tipo float).

Caral 31-03-2010 16:28:59

Hola
Me explico:
En la base de datos puede haber la informacion colocada o guardada de la forma que sea, cuando uno necesita mostrar o hacer calculos con esa infromacion puede formatearla, darle forma, la que se quiera y usarla.
Hay muchas maneras de hacerlo.
Yo nunca he usado el tipo moneda, solo uso el numerico y esto lo hago para llebar los bancos, las facturas etc, etc. y es dinero lo que se representa.
Saludos

ricardo_soria 01-04-2010 03:25:58

Estimados amigos:

Muchas gracias a los dos por sus respuestas. Les comento que decidí volver el campo en Access a tipo 'Moneda', solo para probar, pero aplicando formato a ese campo (accediendo a "Fields Editor" en el componente ADOTable1, y aplicando '$ '#,##0.00 en la propiedad 'DisplayFormat'), y resulta que también apareció correctamente el valor en el DBGrid, así que pensé que tal vez todo había sido problema de visualización... Para confirmar, quité de nuevo el formato del campo... Y se sigue visualizando correctamente !!!!! Claro, sin el formato, pero ya aparece el valor correcto... Esto está para volverse loco, al momento estoy trabajando con el campo tipo Moneda, pero creo que por si acaso lo voy a dejar definitivamente como Numérico / Double, qué tal que después decide volverse loco de nuevo y comienza a desplegar otra vez el "BCD Overflow" en lugar del valor decimal...

En fin, como les decía, muchas gracias por todo.

Saludos !

mcs 01-04-2010 08:23:19

Cita:

Empezado por Caral (Mensaje 358918)
Hola
Me explico:
En la base de datos puede haber la informacion colocada o guardada de la forma que sea, cuando uno necesita mostrar o hacer calculos con esa infromacion puede formatearla, darle forma, la que se quiera y usarla.
Hay muchas maneras de hacerlo.
Yo nunca he usado el tipo moneda, solo uso el numerico y esto lo hago para llebar los bancos, las facturas etc, etc. y es dinero lo que se representa.
Saludos

No me has entendido bien. Los datos no se guardan (o no se deberian guardar) igual cuando usamos el tipo Moneda (coma fija) o cuando se usa el tipo double (coma flotante).

En coma fija, si defines que el campo tiene 5 posiciones enteras y dos decimales, podemos guardar todos los números con dos decimales desde el 99999,99 hasta el -99999,99 (si es un campo con signo). Por el contrario, con coma flotante tenemos los mismos valores, pero hay algunos números que debido a la forma de guardar los valores no tienen representación en binario, como por ejemplo el 0,1 o el 0,01.

Por esto, desde tiempos "remotos", en COBOL siempre se ha usado para guardar los números decimales el formato BCD (o sea, el PIC 99999V99), no para optimización (ocupa mucho más un dato en formato BCD o coma fija que no en coma flotante), pero la precisión es exacta.

Este tipo de error, en cálculos científicos es aceptable, pero en aplicaciones contables no (no puede ser que en cada cálculo se pierda algún céntimo de euro, por ejemplo...)

Para más información, http://en.wikipedia.org/wiki/Floatin...uracy_problems

Saludos,

Marc


La franja horaria es GMT +2. Ahora son las 11:51:51.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi