none
Posible error en update y función Round RRS feed

  • Pregunta

  • Hola a todos:

    Estoy convirtiendo en una tabla de Access 2016 sus campos a decimal(18,5), todas las tablas lo ha hehco perfectamente con la función Round(5), pero tengo esta que os adjunto que hay un campo en que un par de registros no me los convierte y por lo tanto me da error al realizar el insert into en la nueva tabla creada.

    El método que utilizo es el siguiente:

     Public Shared Sub AplicamosRound_VariosAuditoria()
            Try
    
                ' Declaramos una variable Connection
                Using cnn As DbConnection = da.CreateConnection()
    
                    ' Creamos el Commando
                    Dim cmd As DbCommand = cnn.CreateCommand()
    
                    With cmd
                        'Redondeamos los decimales a 5 posiciones para cuando efectuemos la comversión de double a decimal.
                        cmd.CommandText = "UPDATE VariosAuditoria SET Ejer_01 = Round(Ejer_01,5), PorcTot1 = Round(PorcTot1,5), Desv1 = Round(Desv1,5), PorcDesv1 = Round(PorcDesv1,5), Ejer_02 = Round(Ejer_02,5), " &
                                "PorcTot2 = Round(PorcTot2,5), Desv2 = Round(Desv2,5), PorcDesv2 = Round(PorcDesv2,5), Ejer_03 = Round(Ejer_03,5), SimuladorApalanc = Round(SimuladorApalanc,5) "
    
                        ' Asignamos la conexión al comando
                        cmd.Connection = cnn
                        cnn.Open()
                        cmd.ExecuteNonQuery()
                    End With
                End Using
    
            Catch ex As Exception
                MessageBox.Show("Bloqueo en actualizacion Round de datos: 'VariosAuditoria" & vbCrLf & ex.Message & vbCrLf &
               "Acepte para continuar.", "FINANCIAL SYSTEM", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
        End Sub

    Y la imagen de la tabla que no ha corregido esos registros de la columna Ejer_01 es la siguiente:

    No entiendo a que puede ser debido cuando en todas las demás tablas de ha pasado de double a decimal utilizando el método "round" y ha ido perfecto, principalmente porque los campos que llevan el # daban problemas y la función round los evita.

    Si alguien conoce de que forma evitar este problema se lo agradeceré.

    Un cordial saludo.

    Gemma


    domingo, 18 de diciembre de 2016 17:52

Respuestas

  • "gemma_campillo" escribió:

    > Estoy convirtiendo en una tabla de Access 2016 sus campos a decimal(18,5),
    > todas las tablas lo ha hehco perfectamente con la función Round(5), pero
    > tengo esta que os adjunto que hay un campo en que un par de registros no
    > me los convierte y por lo tanto me da error al realizar el insert into
    > en la nueva tabla creada.
    >

    ¿Y por qué regla de tres va a ver un posible error en la consulta UPDATE y la función Round de VBA (Visual Basic para Aplicaciones)? ¿No puedes pensar que QUIZÁS esos valores Double no se pueden convertir a Decimal(18, 5)?

    ¿Has recibido algún mensaje de error al ejecutar la consulta UPDATE que hacen uso de la función ROUND de VBA?

    > Y la imagen de la tabla que no ha corregido esos registros de la
    > columna Ejer_01 es la siguiente:

    ¿Esos dos registros son los ÚNICOS que no se han convertido? Si es así, lo mismo sería más fácil que insertaras manualmente los valores de aquellas columnas del campo Ejer_01 donde aparece el valor -1,#IND, siempre y cuando seas capaz de averiguar el valor numérico de ese número.

    ¡Vamos a ver, Gemma! ¿Los datos de esa tabla pertenecen a algún cliente tuyo en concreto? ¿Las conversiones de Double a Decimal las vas a estar realizando constantemente mientras que el cliente ejecuta tu aplicación, o solamente la vas a realizar una sola vez para posteriormente DISTRIBUIR TU BASE DE DATOS DE ACCESS JUNTO CON TU APLICACIÓN?

    Si es esto último, ¿no crees que sería más fácil que modificaras manualmente el valor de aquellas columnas que no se han actualizado correctamente mediante la función Round de VBA en lugar de estar buscando "posibles errores en ésta o aquella función"? Al menos, eso es lo que yo haría. ;-)


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.


    lunes, 19 de diciembre de 2016 7:55
    Moderador
  • Me alegro que lo hayas solucionado, pero no me has respondido a las preguntas que te he realizado. :-(

    > La pregunta iba no por la solución que ya esta aplicada y corriendo
    > la actualización de cambio de tipos correctamente, si no, por si
    > había alguna razón que yo no atinaba a ver para que esos dos registros
    > no los cambiara a su valor decimal, eso era el problema.

    Pues si todos los valores de los registros se han modificado satisfactoriamente a excepción de esos dos, pues no me queda más que pensar que se deba a que esos dos valores Double no se puedan convertir a Decimal(18, 5), porque otra explicación no le veo.

    > Pero bueno, con un simple update a esos dos campos, antes de empezar la
    > actualización queda corregido y funcionando, después cuando ya está el
    > campo corregido, le genero una actualización de fórmula y toma su valor
    > correcto

    Si te refieres a que ANTES de actualizar el campo con el tipo de dato Decimal(18, 5) actualizas el propio valor del campo Double mediante la función Round(CampoDouble, 5), desde luego es lo mejor que puedes hacer, porque para qué quieres un valor Double como, por ejemplo, 6,23423234231223. Es decir:

    1º) Actualizar el propio campo Double a 5 decimales:

       
    UPDATE Tabla SET CampoDouble = Round(CampoDouble, 5)

        Con lo que el número Double 6,23423234231223 se quedaría redondeado a 5 decimales: 6,23423.

    2º) Actualizar el campo Decimal(18, 5) con el valor del CampoDouble:

       
    UPDATE Table SET CampoDecimal = CampoDouble

    No sé. Pienso que es lo más sencillo, y todo esto lo puede hacer desde la propia interfaz de consultas de Microsoft Access.


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    • Marcado como respuesta gemma_campillo lunes, 19 de diciembre de 2016 10:29
    lunes, 19 de diciembre de 2016 9:58
    Moderador
  • "gemma_campillo" escribió:

    > Está solucionado de la manera que indicas.
    >
    > Pero me continúa quedando la duda del por qué esos dos campos no se
    > pueden convertir, cuando no dan ningún tipo de error trabajando con
    > el campo double, es un misterio.

    El que no se pueda convertir de Double a Decimal entiendo que será porque el resultado de la función Round arrojará un valor que no está dentro del rango permitido por el tipo de dato Decimal, de ahí que trabaje bien cuando el campo es Double y no tan bien cuando es Decimal, por tanto, no creo que sea un "misterio".

    Cambiar el tamaño de un campo numérico

    Es como si deseas asignarle a una variable definida con el tipo de dato System.Decimal el valor máximo de un valor System.Double:

        Dim dob As Double = Double.MaxValue
        Dim dec As Decimal = CDec(dob)  ' --> Error

    Obteniendo una excepción del tipo OverflowException: Valor demasiado grande o demasiado pequeño para un decimal.

    > ... antes de que el submain proceda a sacar el frmpresentación, es decir,
    > nada más arrancar la aplicación se comprueba si la base de datos es access
    > y si se ha hecho la conversión del tipo double al decimal. Si no se ha
    > hecho la conversión, se le saca un form informativo en que ve como se van
    > actualizando las tablas, ...

    Pues entonces, "encomiéndate" al Santo que le tengas una gran devoción para que tus clientes no tengan valores Double en sus tablas con el valor -1,#IND. :-))

    Podrías actuar como te he indicado anteriormente: primero redondear el propio valor Double y después asignárselo al campo Decimal, aunque tengas que ejecutar dos consultas UPDATE.

    Siempre será mejor que se tarde un poquito de tiempo más en ejecutarse la operación antes de que se produzcan un error por una conversión de datos no permitida, porque muchas veces no "cegamos" en que nuestra aplicación se ejecute lo más rápidamente posible y no tenemos en cuenta los fallos de seguridad que podemos cometer por correr tanto. ;-)


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.




    lunes, 19 de diciembre de 2016 11:34
    Moderador

Todas las respuestas

  • "gemma_campillo" escribió:

    > Estoy convirtiendo en una tabla de Access 2016 sus campos a decimal(18,5),
    > todas las tablas lo ha hehco perfectamente con la función Round(5), pero
    > tengo esta que os adjunto que hay un campo en que un par de registros no
    > me los convierte y por lo tanto me da error al realizar el insert into
    > en la nueva tabla creada.
    >

    ¿Y por qué regla de tres va a ver un posible error en la consulta UPDATE y la función Round de VBA (Visual Basic para Aplicaciones)? ¿No puedes pensar que QUIZÁS esos valores Double no se pueden convertir a Decimal(18, 5)?

    ¿Has recibido algún mensaje de error al ejecutar la consulta UPDATE que hacen uso de la función ROUND de VBA?

    > Y la imagen de la tabla que no ha corregido esos registros de la
    > columna Ejer_01 es la siguiente:

    ¿Esos dos registros son los ÚNICOS que no se han convertido? Si es así, lo mismo sería más fácil que insertaras manualmente los valores de aquellas columnas del campo Ejer_01 donde aparece el valor -1,#IND, siempre y cuando seas capaz de averiguar el valor numérico de ese número.

    ¡Vamos a ver, Gemma! ¿Los datos de esa tabla pertenecen a algún cliente tuyo en concreto? ¿Las conversiones de Double a Decimal las vas a estar realizando constantemente mientras que el cliente ejecuta tu aplicación, o solamente la vas a realizar una sola vez para posteriormente DISTRIBUIR TU BASE DE DATOS DE ACCESS JUNTO CON TU APLICACIÓN?

    Si es esto último, ¿no crees que sería más fácil que modificaras manualmente el valor de aquellas columnas que no se han actualizado correctamente mediante la función Round de VBA en lugar de estar buscando "posibles errores en ésta o aquella función"? Al menos, eso es lo que yo haría. ;-)


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.


    lunes, 19 de diciembre de 2016 7:55
    Moderador
  • Hola Enrique:

    Esta mañana muy tempranito ya había hecho un update a 0 de esos de 2 registros para el campo Ejer_01. Por otro lado he repasado (ayer) todo lo que podía estar mal en esos campos. Y todo está correcto trabjando con el antiguo tipo double. Hay muchas otras tablas en  que a través de la propiedad "Round" se ha corregido otros valores que podían llevar el símbolo # porque el campo excedía de su longitud y ningún problema, todos los ha puesto a 5 dígitos como era lo esperado.

    La pregunta iba no por la solución que ya esta aplicada y corriendo la actualización de cambio de tipos correctamente, si no, por si había alguna razón que yo no atinaba a ver para que esos dos registros no los cambiara a su valor decimal, eso era el problema.

    De todas formas y evidentemente la explicación tuya como siempre, me ayuda a conocer más el tema este.

    Pero bueno, con un simple update a esos dos campos, antes de empezar la actualización queda corregido y funcionando, después cuando ya está el campo corregido, le genero una actualización de fórmula y toma su valor correcto

    Ya está.

    Maestro, como siempre muchas gracias por tu ayuda y explicación.

    Un fuerte abrazo.

    Gemma


    lunes, 19 de diciembre de 2016 9:32
  • Me alegro que lo hayas solucionado, pero no me has respondido a las preguntas que te he realizado. :-(

    > La pregunta iba no por la solución que ya esta aplicada y corriendo
    > la actualización de cambio de tipos correctamente, si no, por si
    > había alguna razón que yo no atinaba a ver para que esos dos registros
    > no los cambiara a su valor decimal, eso era el problema.

    Pues si todos los valores de los registros se han modificado satisfactoriamente a excepción de esos dos, pues no me queda más que pensar que se deba a que esos dos valores Double no se puedan convertir a Decimal(18, 5), porque otra explicación no le veo.

    > Pero bueno, con un simple update a esos dos campos, antes de empezar la
    > actualización queda corregido y funcionando, después cuando ya está el
    > campo corregido, le genero una actualización de fórmula y toma su valor
    > correcto

    Si te refieres a que ANTES de actualizar el campo con el tipo de dato Decimal(18, 5) actualizas el propio valor del campo Double mediante la función Round(CampoDouble, 5), desde luego es lo mejor que puedes hacer, porque para qué quieres un valor Double como, por ejemplo, 6,23423234231223. Es decir:

    1º) Actualizar el propio campo Double a 5 decimales:

       
    UPDATE Tabla SET CampoDouble = Round(CampoDouble, 5)

        Con lo que el número Double 6,23423234231223 se quedaría redondeado a 5 decimales: 6,23423.

    2º) Actualizar el campo Decimal(18, 5) con el valor del CampoDouble:

       
    UPDATE Table SET CampoDecimal = CampoDouble

    No sé. Pienso que es lo más sencillo, y todo esto lo puede hacer desde la propia interfaz de consultas de Microsoft Access.


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    • Marcado como respuesta gemma_campillo lunes, 19 de diciembre de 2016 10:29
    lunes, 19 de diciembre de 2016 9:58
    Moderador
  • Hola maestro:

    Está solucionado de la manera que indicas.

    Pero me continúa quedando la duda del por qué esos dos campos no se pueden convertir, cuando no dan ningún tipo de error trabajando con el campo double, es un misterio.

    Respondiendo por otro lado a tu pregunta, si que la aplicación la tiene el cliente corriendo perfectamente, pero ahora al insertarle la posibilidad de trabajar con  sql compact y el sqlserver , se convierten todos los campos double a decimal, antes de que el submain proceda a sacar el frmpresentación, es decir, nada más arrancar la aplicación se comprueba si la base de datos es access y si se ha hecho la conversión del tipo double al decimal. Si no se ha hecho la conversión, se le saca un form informativo en que ve como se van actualizando las tablas, para ello, primero compacto la base de datos, creo un backup de la base de datos y ya se procede a realizar toda la conversión. Si la conversión de todas las tablas es correcta, se sigue indicándole que ya puede convertir la tabla a SqlCompact si quiere, ahora, en caso de que falle, también se le informa del error y se procede a realizar un restore de la base de datos tal como la tenía, en ese caso se tiene que poner en contacto conmigo para solucionar el tema. Todo ello es muy sencillo para el usuario, ya que no tiene que hacer casi nada. Si todo es correcto, ya se le sabre el login y continúa trabajando con su access pero ya convertido a decimal y después desde la pantalla Migración de Datos, puede convertir su base de datos a SqlCompact o sqlserver, reinicia el programa y ya lo tiene todo trabajando en la nueva base de datos.

    Eso es una aparte, ya que internamente también le creo por código las nuevas conexiones de sqlserver y compact (si no existen) en su archivo de configuración, las cuales posteriormente las puede cambiar desde la pantalla Migración de Datos, por lo que el no tiene que tocas para anda el archivo exe.config.

    Bueno más o menos ese el camino elegido para convertir los tipos de la base de datos y dejarla preparada para migrar a otras bases de datos. Indicar también que la base de datos compact y sqlserver sde entregan en el ejecutable de la aplicación.

    Bueno, maestro si he de aclararte algo más me lo indicas.

    Un abrazo.

    Gemma

    lunes, 19 de diciembre de 2016 10:29
  • "gemma_campillo" escribió:

    > Está solucionado de la manera que indicas.
    >
    > Pero me continúa quedando la duda del por qué esos dos campos no se
    > pueden convertir, cuando no dan ningún tipo de error trabajando con
    > el campo double, es un misterio.

    El que no se pueda convertir de Double a Decimal entiendo que será porque el resultado de la función Round arrojará un valor que no está dentro del rango permitido por el tipo de dato Decimal, de ahí que trabaje bien cuando el campo es Double y no tan bien cuando es Decimal, por tanto, no creo que sea un "misterio".

    Cambiar el tamaño de un campo numérico

    Es como si deseas asignarle a una variable definida con el tipo de dato System.Decimal el valor máximo de un valor System.Double:

        Dim dob As Double = Double.MaxValue
        Dim dec As Decimal = CDec(dob)  ' --> Error

    Obteniendo una excepción del tipo OverflowException: Valor demasiado grande o demasiado pequeño para un decimal.

    > ... antes de que el submain proceda a sacar el frmpresentación, es decir,
    > nada más arrancar la aplicación se comprueba si la base de datos es access
    > y si se ha hecho la conversión del tipo double al decimal. Si no se ha
    > hecho la conversión, se le saca un form informativo en que ve como se van
    > actualizando las tablas, ...

    Pues entonces, "encomiéndate" al Santo que le tengas una gran devoción para que tus clientes no tengan valores Double en sus tablas con el valor -1,#IND. :-))

    Podrías actuar como te he indicado anteriormente: primero redondear el propio valor Double y después asignárselo al campo Decimal, aunque tengas que ejecutar dos consultas UPDATE.

    Siempre será mejor que se tarde un poquito de tiempo más en ejecutarse la operación antes de que se produzcan un error por una conversión de datos no permitida, porque muchas veces no "cegamos" en que nuestra aplicación se ejecute lo más rápidamente posible y no tenemos en cuenta los fallos de seguridad que podemos cometer por correr tanto. ;-)


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.




    lunes, 19 de diciembre de 2016 11:34
    Moderador
  • Hola maestro:

    Gracias por tu enorme interés en todos los problemas.

    Está hecho como has indicado y bueno entiendo que el error puede estar en un rango no permitido.

    De todas formas lo tengo arreglado tal como indicas y llevo ya varias pruebas hechas y en ninguna falla.

    Vuelvo a agradecerte como siempre tu gran interés en llegar al final del problema.

    Un fuerte abrazo.

    Gemma

    lunes, 19 de diciembre de 2016 14:41