PDA

Ver la Versión Completa : Ayuda con Number out of Range


luifervm
18-01-2010, 23:44:12
Hola !!

Tengo un problema que aun no puedo determinar que es, espero que alguien pueda darme una luz.

Uso Delphi 6.

Explico lo que pasa:

Tengo un formulario con encabezado y cuerpo. El encabezado tiene sus campos, y el cuerpo esta en una grilla.

Cada una de estas partes tiene su correspondiente dataset asociado, generado automaticamente. Todo funciona bien normal salvo un caso particular.

Tengo unas cifras en el encabezado y cuerpo (el documento es una especie de factura)

Dentro de las tablas de la base de datos, la informacion del encabezado tiene el valor : 23593286244.9000 es de tipo numeric (18,4).

Dentro del cuerpo hay un detalle que tiene la cifra : 17967123357.4600 nuevamente el tipo en la base de datos es numeric (18,4).

El dataset generado toma estos campos de tipo : TFMTBCDField .

El problema es que cuando abro el documento, los valores que veo en los campos son: En el encabezado : 235932862.449 y en el cuerpo veo : 179671233.57. Como pueden ver NADA que ver con lo que realmente esta en la tabla ...

Cuando entro al documento y trato de navegar o hacer cualquier cosa, me sale el error: "Number out of Range".

He tratado de cambiar este tipo de dato a float para probar si es eso, pero no encuentro como. Aunque cambie el tipo de dato dentro del arreglo "FieldDefs" en las propiedades del dataset, el campo sigue mostrandose como tipo TFMTBCDField.

Alguna Idea?

Gracias !

ContraVeneno
19-01-2010, 02:00:28
creo yo que el cambio deberías hacerlo en la base de datos, la cuál no veo si la mencionas... en SQL server y en algunos otros manejadores de bases de datos, tienes el tipo money o currency, que son los datos que deberías manejas si es que quieres manejar datos monetarios...

luifervm
19-01-2010, 14:55:17
Pues mira que eso tambien lo he pensado, pero por tantos procedimientos y demás que existen me parece muy riesgozo hacer ese tipo de cambios. He encontrado un fenómeno curioso y es que si los datos contienen 10 digitos antes de la coma, todo funciona muy bien. Si tienen mas de eso es donde empieza el error. No le encuentro mucho sentido viendo que el tipo de dato TFMTBCDField debería funcionar correctamente. Esto es algun tipo de bug???...alguna idea, gracias !

Lepe
19-01-2010, 15:55:37
http://www.marteens.com/trick3e.htm

Para colmo, las pruebas iniciales que he hecho con el nuevo tipo de campo sugieren que hay problemas con su implementación.

Quizás actualizando los componentes de acceso...

luifervm
18-04-2011, 20:18:26
Hola Gente :

Despues de tanto tiempo me tocó revivir este tema :(... En su momento investigué este asunto lo que más pude y, al parecer, es un BUG del TFMTBCD en el delphi 6. También logré ver que cuando hay valores muy grandes en la BD, por ejemplo, 100.000.000.000,0000 cuando se despliega la información en un grid, tiende a correr la coma de decimales para la izquierda, lo cual hace que el número se vea mas corto y por ende la información que se despliega esta errada totalmente. (Siempre ajusta a 10 posiciones enteras).

Una alternativa a este problema fue al hacer el query un CAST a tipo de dato FLOAT, de esta manera al hacer el CDS y desplegar la información en una grilla se veía bien. Sin embargo, esta solución no es muy aceptable debido a las consecuencias que tiene eso dentro de todo el codigo que ya esta hecho y a toda la reprogramacion dentro de todos los objetos query.

Quería preguntar si alguien tiene alguna sugerencia, solucion o idea, para cambiar esto con el menor traumatismo -o si alguien conoce algun método de manejar este bug-, ya que varias sugerencias que he visto es cambiar los tipos de datos de la BD a currency para que al hacer el CDS se tome como otro tipo de dato que no tiene problemas, pero los tipos de dato en la BD deben ser DECIMAL(18,4). :(. Además, este cambio implicaría tener que revisar absolutamente todo el código tanto de la BD, triggers, SP, Functions y demás y de igual forma revisar Todo el codigo delphi :S ...

Al González
19-04-2011, 07:21:38
Hola.

Casi siempre que encuentro en Delphi algún defecto incómodo (es de esperarse que existan al ser una herramienta de programación tan vasta), como el que explicas, y tal defecto me impide conseguir el objetivo que tengo trazado en el proyecto en cuestión, busco la manera de solventarlo.

Primero trato de averiguar si ya existe una aceptación oficial del mismo por parte del fabricante (http://qc.embarcadero.com/wc/qcmain.aspx), con su respectivo parche o solución alternativa.

De no encontrar solución hecha que me satisfaga, estudio el código fuente de la VCL procurando descubrir la causa (a veces de todas formas hago esto para conocer los detalles del asunto).

Ocasionalmente encuentro la razón del fallo, pero también me ha pasado que llego hasta donde el código fuente transfiere el control a una DLL de la que no hay código fuente disponible. Dependiendo de la calidad y claridad de los datos obtenidos, elaboro algún tipo de solución, que a veces resulta elegante y en otros casos una auténtica chapuza.

El caso por el que uno cruza los dedos es cuando el defecto en cuestión se localiza en el código fuente de un método virtual (o mensaje), tal método no hace referencia a elementos privados para los cuales no haya cuando menos acceso protegido (clásicos campos "FOnlyForMyEyes") y la clase a la que pertenece dicho método puede ser sustituida para cualquier elemento que haga uso de ella. Cuando es así, puede derivarse una clase hija redefiniendo el método en cuestión, aplicando en él el parche o código que ayude a evitar el defecto.

Pero también hay situaciones donde el problema reside en un método estático o función suelta, o el método es virtual y por lo tanto redefinible pero hace montones de referencias a elementos, permítanme la expresión, ultraprivados, y eso complica aplicar un parche sin modificar directamente el código fuente. De cualquier manera, cada caso tiene sus particularidades.

Te recomiendo buscar en QualityCentral si este error ha sido ya reportado, en qué estado se encuentra y qué soluciones hay. Y, cuando así prefieras también, estudiar la clase TFmtBCDField, valiéndote del propio depurador de Delphi además del código fuente de la VCL, para tratar de encontrar la causa del problema y con ello ver si es posible implementar una solución.

Un saludo.

Al González. :)

luifervm
29-04-2011, 18:08:12
Hola :

En realidad pensé igual en su momento, de hecho llegue a tomar una unit FMTBCD mas reciente, incorporarla, recompilar todas las dependencias y probar, pero eso fue peor. Aunque compiló, luego tuve otro tipo de errores muy raros y preferí revertir todos los cambios que hice.

Sin Embargo, encontré la solución al problema. Es un problema del DELPHI, en efecto, pero también es un problema de conceptos matemáticos y como se aplican en este componente:

Les explico:

Los tipos de dato en la BD SQL SERVER son DECIMAL (18,4).

Al traer los campos en los query y cds, etc. Por defecto las propiedades del control estaban mal. Debo mencionar las 3 propiedades mas importantes:

DisplayWidth

Precision

Size

Los valores equivocados en estas propiedades, que fueron colocados automáticamente, estaban haciendo que obtuviera errores de "number out of range" o que al tomar la informacion de la BD el numero que aparecía en los controles estaba "cortado".

La solución, para este tipo de dato fue tomar los valores de la siguiente manera:

DisplayWidth : 23

Precision : 22

Size : 4


Las razones: DisplayWidth es la cantidad de "campos" visibles en un grid, caja de texto, etc. Se necesita un campo adicional para la COMA. en este caso el tipo de dato NUMERIC (18,4) + 1 = 23 posiciones.

Precision: Este campo se refiere al numero de CIFRAS SIGNIFICATIVAS. en este caso requiero que sean 18 + 4 = 22 !!!!!!

Size : La cantidad de DECIMALES presentes en el dato, es decir 4 !!!!!

Con esto, desaparecieron todos los problemas !!!!

Espero que esto le pueda servir a alguien más, ya que no se imaginan la cantidad de tiempo y de investigación que me llevó este problema.


Saludos !