none
Error al copiar tablas de una base de datos SqlCompact a Access

    Pregunta

  • Hola a todos:

    Tengo un error que se produce en el momento de querer exportar una/s tabla/s de SqlCompact 4.0 a Access 2007, solo se me produce dicho error cuando es access el receptor de los datos, no cuando se hace al revés, es decir de Access a SqlComptact funciona perfectamente, pero no así cuando lo preciso importar a Access.

    El código es el siguiente:

    Función para crear el datable de SqlCompact.

      Public Shared Function GetDataSqlCompact40() As DataTable
            Dim cadenaConexion As String = Configuracion.CadenaConexion
            Dim dt As New DataTable()
            Using cnn As New SqlCeConnection(cadenaConexion)
                Dim cmd As SqlCeCommand = cnn.CreateCommand()
                Select Case strNombreTabla
                    Case "Empresas"
                        cmd.CommandText = "SELECT * FROM Empresas"
                    Case "CapCirculante"
                        cmd.CommandText = "SELECT * FROM CapCirculante"
                    Case "BalSitExpl"
                        cmd.CommandText = "SELECT * FROM BalSitExpl"
                    Case "Balances"
                        cmd.CommandText = "SELECT * FROM Balances"
                    Case "CNAE"
                        cmd.CommandText = "SELECT * FROM CNAE"
                    Case "CnaeColombia"
                        cmd.CommandText = "SELECT * FROM CnaeColombia"
                    Case "CNAE_Col"
                        cmd.CommandText = "SELECT * FROM CNAE_Col"
                    Case "CnaeGeneral"
                        cmd.CommandText = "SELECT * FROM CnaeGeneral"
                    Case "CuadroAnalitPyG"
                        cmd.CommandText = "SELECT * FROM CuadroAnalitPyG"
                    Case "CuadroMando"
                        cmd.CommandText = "SELECT * FROM CuadroMando"
                    Case "EFE"
                        cmd.CommandText = "SELECT * FROM EFE"
                    Case "EOAF"
                        cmd.CommandText = "SELECT * FROM EOAF"
                    Case "Flujos"
                        cmd.CommandText = "SELECT * FROM Flujos"
                    Case "Imagenes"
                        cmd.CommandText = "SELECT * FROM Imagenes"
                    Case "NOF"
                        cmd.CommandText = "SELECT * FROM NOF"
                    Case "PARAMETROS"
                        cmd.CommandText = "SELECT * FROM PARAMETROS"
                    Case "PatrimNeto"
                        cmd.CommandText = "SELECT * FROM PatrimNeto"
                    Case "PatrimNetoPymes"
                        cmd.CommandText = "SELECT * FROM PatrimNetoPymes"
                    Case "ProyectoInversion"
                        cmd.CommandText = "SELECT * FROM ProyectoInversion"
                    Case "Ratios"
                        cmd.CommandText = "SELECT * FROM Ratios"
                    Case "SimuladorSectorial"
                        cmd.CommandText = "SELECT * FROM SimuladorSectorial"
                    Case "SMediosSA"
                        cmd.CommandText = "SELECT * FROM SMediosSA"
                    Case "TAM"
                        cmd.CommandText = "SELECT * FROM TAM"
                    Case "TotalesGraficos"
                        cmd.CommandText = "SELECT * FROM TotalesGraficos"
                    Case "TotalesGraficosParciales"
                        cmd.CommandText = "SELECT * FROM TotalesGraficosParciales"
                    Case "TraspasoFlujos"
                        cmd.CommandText = "SELECT * FROM TraspasoFlujos"
                    Case "Usuarios"
                        cmd.CommandText = "SELECT * FROM Usuarios"
                    Case "Valoraciones"
                        cmd.CommandText = "SELECT * FROM Valoraciones"
                    Case "Varios"
                        cmd.CommandText = "SELECT * FROM Varios"
                    Case "VariosAuditoria"
                        cmd.CommandText = "SELECT * FROM VariosAuditoria"
                End Select
    
                Dim da As New SqlCeDataAdapter(cmd)
    
                da.MissingSchemaAction = MissingSchemaAction.AddWithKey
    
                'Rellenar el datatable con los datos del adaptador
                da.Fill(dt)
    
                ' Si no se ha producido un error, guardamos en las
                ' propiedades extendidas del objeto DataTable la
                ' consulta SQL de selección que hemos utilizado
                ' para obtener los datos de la tabla de SqlCompact.
                '
                dt.ExtendedProperties.Add("CommandText", cmd.CommandText)
    
                bolBorradoDatos = True
    
            End Using
    
            Return dt
    
        End Function

    y Ahora la actualización de Access a través de dicho datatable.

     
     Public Shared Function ImportacionAAccessDesdeSqlCompact40(dt As DataTable) As Integer
    
            ' Recorremos todas las filas del objeto DataTable  para establecer como añadido cada objeto DataRow.
            '
            For Each row As DataRow In dt.Rows
                row.SetAdded()
            Next
    
            Configuracion.CadenaConexion()
            Dim PasswordEncriptado As String = System.Text.Encoding.Default.GetString(System.Convert.FromBase64String("xxxncw=="))
            Dim cnn As New OleDbConnection(ConfigurationManager.ConnectionStrings("MiCadenaConexion").ConnectionString & PasswordEncriptado)
    
            Dim transaction As OleDbTransaction = Nothing
    
            cnn.Open()
    
            Try
                'Procedemos a borrar los registros de la tablas antes de importar.
                Dim sql As String
    
                If strNombreTabla = "Empresas" = True Then
                    sql = "DELETE  FROM Empresas"
                ElseIf strNombreTabla = "CapCirculante" = True Then
                    sql = "DELETE  FROM CapCirculante"
                ElseIf strNombreTabla = "BalSitExpl" = True Then
                    sql = "DELETE  FROM BalSitExpl"
                ElseIf strNombreTabla = "Balances" = True Then
                    sql = "DELETE  FROM Balances"
                ElseIf strNombreTabla = "CNAE" = True Then
                    sql = "DELETE  FROM CNAE"
                ElseIf strNombreTabla = "CNAE_Col" = True Then
                    sql = "DELETE  FROM CNAE_Col"
                ElseIf strNombreTabla = "CnaeColombia" = True Then
                    sql = "DELETE  FROM CnaeColombia"
                ElseIf strNombreTabla = "CnaeGeneral" = True Then
                    sql = "DELETE  FROM CnaeGeneral"
                ElseIf strNombreTabla = "CuadroAnalitPyG" = True Then
                    sql = "DELETE  FROM CuadroAnalitPyG"
                ElseIf strNombreTabla = "CuadroMando" = True Then
                    sql = "DELETE  FROM CuadroMando"
                ElseIf strNombreTabla = "EFE" = True Then
                    sql = "DELETE  FROM EFE"
                ElseIf strNombreTabla = "EOAF" = True Then
                    sql = "DELETE  FROM EOAF"
                ElseIf strNombreTabla = "Flujos" = True Then
                    sql = "DELETE  FROM Flujos"
                ElseIf strNombreTabla = "Imagenes" = True Then
                    sql = "DELETE  FROM Imagenes"
                ElseIf strNombreTabla = "NOF" = True Then
                    sql = "DELETE  FROM NOF"
                ElseIf strNombreTabla = "PARAMETROS" = True Then
                    sql = "DELETE  FROM PARAMETROS"
                ElseIf strNombreTabla = "PatrimNeto" = True Then
                    sql = "DELETE  FROM PatrimNeto"
                ElseIf strNombreTabla = "PatrimNetoPymes" = True Then
                    sql = "DELETE  FROM PatrimNetoPymes"
                ElseIf strNombreTabla = "ProyectoInversion" = True Then
                    sql = "DELETE  FROM ProyectoInversion"
                ElseIf strNombreTabla = "Ratios" = True Then
                    sql = "DELETE  FROM Ratios"
                ElseIf strNombreTabla = "SimuladorSectorial" = True Then
                    sql = "DELETE  FROM SimuladorSectorial"
                ElseIf strNombreTabla = "SMediosSA" = True Then
                    sql = "DELETE  FROM SMediosSA"
                ElseIf strNombreTabla = "TAM" = True Then
                    sql = "DELETE  FROM TAM"
                ElseIf strNombreTabla = "TotalesGraficos" = True Then
                    sql = "DELETE  FROM TotalesGraficos"
                ElseIf strNombreTabla = "TotalesGraficosParciales" = True Then
                    sql = "DELETE  FROM TotalesGraficosParciales"
                ElseIf strNombreTabla = "TraspasoFlujos" = True Then
                    sql = "DELETE  FROM TraspasoFlujos"
                ElseIf strNombreTabla = "Usuarios" = True Then
                    sql = "DELETE  FROM Usuarios"
                ElseIf strNombreTabla = "Valoraciones" = True Then
                    sql = "DELETE  FROM Valoraciones"
                ElseIf strNombreTabla = "Varios" = True Then
                    sql = "DELETE  FROM Varios"
                ElseIf strNombreTabla = "VariosAuditoria" = True Then
                    sql = "DELETE  FROM VariosAuditoria"
                Else
                    sql = ""
                End If
    
                ' Creamos el Commando
                Dim cmd1 As New OleDbCommand(sql, cnn)
    
                cmd1.ExecuteNonQuery()
                Dim nrorows As Integer = dt.Rows.Count
                If nrorows <> 0 Then
                    bolBorradoDatos = True
                Else
                    bolBorradoDatos = False
                End If
    
                transaction = cnn.BeginTransaction()
    
                ' Recuperamos la consulta SQL de selección existente en
                ' las propiedades extendidas del objeto DataTable.
                '
                Dim commandText As String = Convert.ToString(dt.ExtendedProperties("CommandText"))
    
                If (commandText = String.Empty) Then
                    Throw New ArgumentException("No se ha especificado la consulta SQL de selección.")
                End If
    
                Dim cmd As OleDbCommand = cnn.CreateCommand()
                cmd.CommandText = commandText
                cmd.Transaction = transaction
    
                Dim da As New OleDbDataAdapter(cmd)
                da.MissingSchemaAction = MissingSchemaAction.AddWithKey
    
                Dim cb As New OleDbCommandBuilder(da)
                cb.QuotePrefix = "["
                cb.QuoteSuffix = "]"
    
                'Insertamos nuevos registros 
                da.InsertCommand = cb.GetInsertCommand()
    
                ' Enviamos los datos del objeto DataTable de sqlCompact a la base de Access.
                Dim n As Integer = da.Update(dt)     '// Aquí da la excepción.
    
                transaction.Commit()
    
                ' Devolvemos el número de registros afectados.
                Return n
                If n <> 0 Then
                    bolCargaDatos = True
                Else
                    bolCargaDatos = False
                End If
    
            Catch ex As Exception
                MessageBox.Show("Error en la importación / exportación de datos. " & vbCrLf &
                      "No se ha podido realizar la transacción a la nueva base." & vbCrLf & ex.Message & vbCrLf &
                  "Acepte para continuar.", "FINANCIAL SYSTEM", MessageBoxButtons.OK, MessageBoxIcon.Error)
    
                transaction.Rollback()
                Throw
    
            Finally
                ' Cerrar y destruir la conexión.
                cnn.Dispose()
    
            End Try
        End Function
    

    El error que muestra es el siguiente:  No se ha podido realizar la transacción a la nueva base. "No coinciden los tipos de datos en la expresión de criterios". descrito en la pregunta y por mas vueltas que le he dado, comprobado la tabla "empresas", etc., no encuentro por qué me lo da. He repasado todos los campos, tipos, etc., y perfecto, el tema está en que si exporto de access e importo en SqlCompact o bien en sqlserver lo hace perfectamente, recorre correctamente todas las tablas rellenando los campos sin problemas.

    Bueno, un cordial saludo a todos.

    Gemma

    jueves, 5 de enero de 2017 13:36

Respuestas

  • "gemma_campillo" escribió:

    > El error que muestra es el siguiente: "No coinciden los tipos de datos en la expresión de criterios".
    >
    > y por mas vueltas que le he dado, comprobado la tabla "empresas", etc., no encuentro por qué me lo da.

    Pues es fácil saber el motivo, ya que el típico error "No coinciden los tipos de datos en la expresión de criterios" suele aparecer cuando estás queriendo insertar un valor en un campo que no coincide con el tipo de dato que tiene definido dicho campo.

    > Tengo un error que se produce en el momento de querer exportar
    > una/s tabla/s de SqlCompact 4.0 a Access 2007 ...

    Si no es mucho preguntar, ¿para qué quieres hacer eso? Se supone que tienes correctos los datos en Access. Si es así, ¿cuál es el motivo de que quieras rellenar las tablas de la base de datos de Access con las correspondientes de la base de SQL Compact? Te lo pregunto porque puede haber una incompatibilidad entre los tipos de datos de unas y otras.

    Ten en cuenta que estás recuperando un objeto DataTable, configurado con los datos recuperados de la tabla de SQL Compact (GetDataSqlCompact40), y se lo estás queriendo pasar a la tabla de Access (ImportacionAAccessDesdeSqlCompact40) mediante el método Update de un adaptador de datos configurado para Access, no para SQL Compact, por lo que en algunos casos puede que la operación se realice satisfactoriamente, y otras no tanto, dependiendo de los tipos de datos de las tablas.

    Esa manera de pasar datos mediante el método Update de un adaptador de datos, no quiere decir que sea una panacea para solucionar el traspaso de datos entre diferentes orígenes de datos, porque lo primero que tienes que hacer es verificar si los valores son compatibles entre ambas tablas.

    Quiero recordar que en la base de datos de Access tenías definidos tipos de datos Decimal con una precisión 18 y escala 5. ¿Así es como están en las tablas de SQL Compact?

    Me ha dado por hacer una prueba y no he tenido ningún mensaje de error a la hora de insertar los datos de SQL Compact en una tabla con igual estructura de Access, por lo que en principio se han insertado todos los datos. Pero a la hora de abrir la tabla de Access, me he encontrado que los valores de los campos Decimal (18, 2) se han insertado como enteros, perdiendo por completo su valor decimal, por lo que desde luego no me fiaría ya de utilizar un objeto DataTable para pasar datos de SQL Compact a Access donde existan campos con el tipo de dato Decimal.

    Creo que el problema del error "No coinciden los tipos de datos en la expresión de criterios" puede que esté en una incompatibilidad de tipos de datos, y ahora tendrías que buscar qué valores son los que no son compatibles. Y aparte, que te puede pasar lo que a mí me ha sucedido. :-(

    Tu verás si te interesa volver a Access con unos datos existentes en un objeto DataTable y que provienen de SQL Compact. La operación contraria (de Access a SQL Compact) puede que no dé problemas, no así en la dirección contraria. ;-)


    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.



    jueves, 5 de enero de 2017 18:33
    Moderador
  • "gemma_campillo" escribió:

    > De todas formas, eso de poder pasar la base de compact a access no creo que se
    > de en ningún momento, pero por si acaso, voy a mirar primero que pasa con esos
    > campos, ya que al revés funciona perfectamente, si están con 5 decimales, al
    > hacer el traspaso, salen todos con sus 5 decimales y todo repasado y cuadrado.

    Al revés funciona perfectamente, y se ejecuta en un abrir y cerrar de ojos. Pero lee bien los resultados que yo he obtenido, que me parece a mí que te lo has saltado:

    [...] Me ha dado por hacer una prueba y no he tenido ningún mensaje de error a la hora de insertar los datos de SQL Compact en una tabla con igual estructura de Access, por lo que en principio se han insertado todos los datos. Pero a la hora de abrir la tabla de Access, me he encontrado que los valores de los campos Decimal (18, 2) se han insertado como enteros, perdiendo por completo su valor decimal, por lo que desde luego no me fiaría ya de utilizar un objeto DataTable para pasar datos de SQL Compact a Access.[...]

    ¿Has leído bien el párrafo? Que aunque no he tenido ningún error al importar los datos de SQL Compact a Access, ¡los valores decimales HAN DESAPARECIDO por arte de magia de la tabla de Access!

    Si quieres hacer una prueba, tan solo tienes que indicar que las filas erróneas no se inserten en la tabla de Access. Para ello, inserta en ese módulo el siguiente procedimiento:

       Private Shared Sub OnRowUpdated(sender As Object, args As OleDbRowUpdatedEventArgs)
    
            If (args.Status = UpdateStatus.ErrorsOccurred) Then
    
                args.Row.RowError = args.Errors.Message
    
                ' Indicar que la fila actual no se actualice
                args.Status = UpdateStatus.SkipCurrentRow
    
                Dim msg As String =
                    String.Format("{0} Primer campo de la fila con errores: {1}{2}",
                                  args.Row.RowError, Environment.NewLine, args.Row.Item(0))
    
            End If
    
        End Sub
    

    Y ahora, en la función ImportacionAAccessDesdeSqlCompact40 añade el controlador para el evento RowUpdated del objeto OleDbDataAdapter:

        ' Declaramos el adaptador de datos
        Dim da As New OleDbDataAdapter(cmd)
    
        ' Añadimos el controlador para el evento RowUpdated
        AddHandler da.RowUpdated, AddressOf OnRowUpdated
    
        da.MissingSchemaAction = MissingSchemaAction.AddWithKey
    

    Lo que está en negrita es lo que tienes que insertar entre las dos líneas que aparecen.

    Si se inserta alguna fila en la tabla de Access, la abres y dime si han desaparecido los valores decimales de aquellos campos definidos con el tipo de dato Decimal(18, 5).


    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 jueves, 5 de enero de 2017 20:13
    jueves, 5 de enero de 2017 19:40
    Moderador
  • "gemma_campillo" escribió:

    > Yendo al tema que me preguntabas, esos registros que se han insertado son
    > correctos en cuanto a sus decimales, los lleva correctamente a 5 dec. (18,5).

    Pues yo, por ahora, no puedo decir lo mismo:

    Los valores correspondientes a los campos Base, IVA y Total, están definidos con el tipo de dato Decimal(18,2), tanto en Access como en SQL Compact, y a la hora de pasar de SQL Compact a Access, y por motivos que desconozco por ahora, han desaparecido por completo el valor decimal, quedándose en valores enteros, por lo que yo no me puedo fiar ya de realizar ese traspaso de datos.

    > En una segunda pasada si que ya ha insertado valores en algunas tabla, en
    > otras no, y en la tabla que ha insertado, no los ha insertado todos.
    >

    Se han insertado unos valores sí y otros no, porque seguramente has añadido el evento RowUpdated del objeto OleDbDataAdapter, tal cual te indiqué en una respuesta anterior, donde se indica que los registros con errores NO SE TOMEN EN CUENTA, y por tanto, NO SE INSERTAN.

    Por supuesto, éste controlador de evento lo DEBERÁS DE ELIMINAR de tu proyecto porque entonces no tiene ningún sentido que declares un objeto OleDbTransaction en el procedimiento ImportacionAAccessDesdeSqlCompact40 para revertir la operación si ésta falla, ya que, o se insertan TODOS los registros o no se inserta ninguno.

    El evento en cuestión es para depurar los valores de los registros en fase de pruebas, no para que se ejecute en un producto final. ¿Me explico?

    > No acabo de entender nada de esto que pasa.

    Pues que tienes que asegurarte, y bien, que los datos existentes en la base de SQL Compact son compatibles con los tipos de datos definidos en las tablas de la base de datos de Access, así de claro, pero que yo, por los resultados de la prueba que he realizado, por ahora me olvidaría de pasar los datos a Access desde una base de SQL Compact, al menos, utilizando el método Update de un objeto OleDbDataAdapter al que se le pasa un objeto DataTable que ha sido rellenado por un adaptador de datos propio de SQL Compact.

    ¡Feliz día de Reyes Magos!


    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.


    viernes, 6 de enero de 2017 5:54
    Moderador

Todas las respuestas

  • "gemma_campillo" escribió:

    > El error que muestra es el siguiente: "No coinciden los tipos de datos en la expresión de criterios".
    >
    > y por mas vueltas que le he dado, comprobado la tabla "empresas", etc., no encuentro por qué me lo da.

    Pues es fácil saber el motivo, ya que el típico error "No coinciden los tipos de datos en la expresión de criterios" suele aparecer cuando estás queriendo insertar un valor en un campo que no coincide con el tipo de dato que tiene definido dicho campo.

    > Tengo un error que se produce en el momento de querer exportar
    > una/s tabla/s de SqlCompact 4.0 a Access 2007 ...

    Si no es mucho preguntar, ¿para qué quieres hacer eso? Se supone que tienes correctos los datos en Access. Si es así, ¿cuál es el motivo de que quieras rellenar las tablas de la base de datos de Access con las correspondientes de la base de SQL Compact? Te lo pregunto porque puede haber una incompatibilidad entre los tipos de datos de unas y otras.

    Ten en cuenta que estás recuperando un objeto DataTable, configurado con los datos recuperados de la tabla de SQL Compact (GetDataSqlCompact40), y se lo estás queriendo pasar a la tabla de Access (ImportacionAAccessDesdeSqlCompact40) mediante el método Update de un adaptador de datos configurado para Access, no para SQL Compact, por lo que en algunos casos puede que la operación se realice satisfactoriamente, y otras no tanto, dependiendo de los tipos de datos de las tablas.

    Esa manera de pasar datos mediante el método Update de un adaptador de datos, no quiere decir que sea una panacea para solucionar el traspaso de datos entre diferentes orígenes de datos, porque lo primero que tienes que hacer es verificar si los valores son compatibles entre ambas tablas.

    Quiero recordar que en la base de datos de Access tenías definidos tipos de datos Decimal con una precisión 18 y escala 5. ¿Así es como están en las tablas de SQL Compact?

    Me ha dado por hacer una prueba y no he tenido ningún mensaje de error a la hora de insertar los datos de SQL Compact en una tabla con igual estructura de Access, por lo que en principio se han insertado todos los datos. Pero a la hora de abrir la tabla de Access, me he encontrado que los valores de los campos Decimal (18, 2) se han insertado como enteros, perdiendo por completo su valor decimal, por lo que desde luego no me fiaría ya de utilizar un objeto DataTable para pasar datos de SQL Compact a Access donde existan campos con el tipo de dato Decimal.

    Creo que el problema del error "No coinciden los tipos de datos en la expresión de criterios" puede que esté en una incompatibilidad de tipos de datos, y ahora tendrías que buscar qué valores son los que no son compatibles. Y aparte, que te puede pasar lo que a mí me ha sucedido. :-(

    Tu verás si te interesa volver a Access con unos datos existentes en un objeto DataTable y que provienen de SQL Compact. La operación contraria (de Access a SQL Compact) puede que no dé problemas, no así en la dirección contraria. ;-)


    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.



    jueves, 5 de enero de 2017 18:33
    Moderador
  • Hola maestro.

    Los tipos de datos "en principio" son los mismos.

    Respondiendo a tu pregunta, el motivo de que el usuario pueda volver a Access desde SqlCompact o Server, es nada más que eso, darle la oportunidad de pasar a Access, que no creo que lo haga nadie, pero eso lo decidirá el usuario en última instancia. Es el único error que hoy presenta el programa, y mira que hay cambio de tipos en los que ya lo tienen instalado y después de los cambios de tipo a decimal(18,5) vendrá la conversión de Access a sql compact, todo va perfecto, ningún error, excepto esto de access que pueden ser los campos "SI/NO" es decir, los booleanos y también el campo fecha de Access que lo tengo como Date en COmpact. De todas formas, eso de poder pasar la base de compact a access no creo que se de en ningún momento, pero por si acaso, voy a mirar primero que pasa con esos campos, ya que al revés funciona perfectamente, si están con 5 decimales, al hacer el traspaso, salen todos con sus 5 decimales y todo repasado y cuadrado.

    Por último como que la tabla de access (si estás en SqlCompact) al hacer el traspaso los campos se ponen a 0, quizás la solución también pueda ser un simple insert into y tendrá que funcionar igual.

    Bueno maestro, ya se que a veces vengo con preguntas raras y complicadas, pero es a lo que no llego pero siempre con tus explicaciones entiendo mejor donde se puede localizar el problemas.

    En fin, muchas gracias querido amigo y que los Retes se porten bien contigo. Lo que no se, se te has portado bien el año pasado, porque si no ya sabes lo que te traen.

    Un fuerte abrazo.

    Gemma

    jueves, 5 de enero de 2017 18:54
  • "gemma_campillo" escribió:

    > De todas formas, eso de poder pasar la base de compact a access no creo que se
    > de en ningún momento, pero por si acaso, voy a mirar primero que pasa con esos
    > campos, ya que al revés funciona perfectamente, si están con 5 decimales, al
    > hacer el traspaso, salen todos con sus 5 decimales y todo repasado y cuadrado.

    Al revés funciona perfectamente, y se ejecuta en un abrir y cerrar de ojos. Pero lee bien los resultados que yo he obtenido, que me parece a mí que te lo has saltado:

    [...] Me ha dado por hacer una prueba y no he tenido ningún mensaje de error a la hora de insertar los datos de SQL Compact en una tabla con igual estructura de Access, por lo que en principio se han insertado todos los datos. Pero a la hora de abrir la tabla de Access, me he encontrado que los valores de los campos Decimal (18, 2) se han insertado como enteros, perdiendo por completo su valor decimal, por lo que desde luego no me fiaría ya de utilizar un objeto DataTable para pasar datos de SQL Compact a Access.[...]

    ¿Has leído bien el párrafo? Que aunque no he tenido ningún error al importar los datos de SQL Compact a Access, ¡los valores decimales HAN DESAPARECIDO por arte de magia de la tabla de Access!

    Si quieres hacer una prueba, tan solo tienes que indicar que las filas erróneas no se inserten en la tabla de Access. Para ello, inserta en ese módulo el siguiente procedimiento:

       Private Shared Sub OnRowUpdated(sender As Object, args As OleDbRowUpdatedEventArgs)
    
            If (args.Status = UpdateStatus.ErrorsOccurred) Then
    
                args.Row.RowError = args.Errors.Message
    
                ' Indicar que la fila actual no se actualice
                args.Status = UpdateStatus.SkipCurrentRow
    
                Dim msg As String =
                    String.Format("{0} Primer campo de la fila con errores: {1}{2}",
                                  args.Row.RowError, Environment.NewLine, args.Row.Item(0))
    
            End If
    
        End Sub
    

    Y ahora, en la función ImportacionAAccessDesdeSqlCompact40 añade el controlador para el evento RowUpdated del objeto OleDbDataAdapter:

        ' Declaramos el adaptador de datos
        Dim da As New OleDbDataAdapter(cmd)
    
        ' Añadimos el controlador para el evento RowUpdated
        AddHandler da.RowUpdated, AddressOf OnRowUpdated
    
        da.MissingSchemaAction = MissingSchemaAction.AddWithKey
    

    Lo que está en negrita es lo que tienes que insertar entre las dos líneas que aparecen.

    Si se inserta alguna fila en la tabla de Access, la abres y dime si han desaparecido los valores decimales de aquellos campos definidos con el tipo de dato Decimal(18, 5).


    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 jueves, 5 de enero de 2017 20:13
    jueves, 5 de enero de 2017 19:40
    Moderador
  • Hola maestro:

    Estoy preparando la cena y te digo algo, de cualquier manera de Access a SqlCompact lo hace perfectamente y no se come ningún decimal.

    Mira por ejemplo el Eje_01 y lo hace correctamente, lleva sus decimales.

    Me pongo con lo que me has escrito en un ratito.

    Muchas gracias Enrique.

    Un abrazo.

    Gemma

    jueves, 5 de enero de 2017 20:13
  • "gemm_campillo" escribió:

    de cualquier manera de Access a SqlCompact lo hace perfectamente y no se come ningún decimal.

    Me refería al revés: de SQL Compact a 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.

    jueves, 5 de enero de 2017 20:38
    Moderador
  • Hola Enrique:

    Bueno, ya el error que daba en el update no lo da. Pasa por todas las tablas, pero no inserta o importa ningún registro, todo a 0. No te preocupes mucho porque a lo mejor es peor el remedio que la enfermedad. A veces quiero rizar tanto el rizo (a lo que me has enseñado) que no se puede. Estoy hasta las narices del tema este de la importación.

    Bueno, maestro descansa y muchas gracias como siempre.

    Un fuerte abrazo.

    Gemma

    jueves, 5 de enero de 2017 20:54
  • Hola maestro:

    En una segunda pasada si que ya ha insertado valores en algunas tabla, en otras no, y en la tabla que ha insertado, no los ha insertado todos. Yendo al tema que me preguntabas, esos registros que se han insertado son correctos en cuanto a sus decimales, los lleva correctamente a 5 dec. (18,5).

    No acabo de entender nada de esto que pasa. Bueno, buenas noches y que descanses.

    Gemma

    jueves, 5 de enero de 2017 21:16
  • "gemma_campillo" escribió:

    > Yendo al tema que me preguntabas, esos registros que se han insertado son
    > correctos en cuanto a sus decimales, los lleva correctamente a 5 dec. (18,5).

    Pues yo, por ahora, no puedo decir lo mismo:

    Los valores correspondientes a los campos Base, IVA y Total, están definidos con el tipo de dato Decimal(18,2), tanto en Access como en SQL Compact, y a la hora de pasar de SQL Compact a Access, y por motivos que desconozco por ahora, han desaparecido por completo el valor decimal, quedándose en valores enteros, por lo que yo no me puedo fiar ya de realizar ese traspaso de datos.

    > En una segunda pasada si que ya ha insertado valores en algunas tabla, en
    > otras no, y en la tabla que ha insertado, no los ha insertado todos.
    >

    Se han insertado unos valores sí y otros no, porque seguramente has añadido el evento RowUpdated del objeto OleDbDataAdapter, tal cual te indiqué en una respuesta anterior, donde se indica que los registros con errores NO SE TOMEN EN CUENTA, y por tanto, NO SE INSERTAN.

    Por supuesto, éste controlador de evento lo DEBERÁS DE ELIMINAR de tu proyecto porque entonces no tiene ningún sentido que declares un objeto OleDbTransaction en el procedimiento ImportacionAAccessDesdeSqlCompact40 para revertir la operación si ésta falla, ya que, o se insertan TODOS los registros o no se inserta ninguno.

    El evento en cuestión es para depurar los valores de los registros en fase de pruebas, no para que se ejecute en un producto final. ¿Me explico?

    > No acabo de entender nada de esto que pasa.

    Pues que tienes que asegurarte, y bien, que los datos existentes en la base de SQL Compact son compatibles con los tipos de datos definidos en las tablas de la base de datos de Access, así de claro, pero que yo, por los resultados de la prueba que he realizado, por ahora me olvidaría de pasar los datos a Access desde una base de SQL Compact, al menos, utilizando el método Update de un objeto OleDbDataAdapter al que se le pasa un objeto DataTable que ha sido rellenado por un adaptador de datos propio de SQL Compact.

    ¡Feliz día de Reyes Magos!


    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.


    viernes, 6 de enero de 2017 5:54
    Moderador
  • Hola maestro, buenos días.

    Bueno, no le des más vueltas, lo vamos a dejar tal como está y en una palabra, indicar que no se pueden traspasar los datos a access por motivos "x", ya nos ha dado  bastantes dolores de cabeza este tema.

    Con que es pronto y ya lo tengo preparado o casi desde esta madrugada, voy a hacer un insert into de una tabla a otra a ver si así lo coge bien, que no, se acabó, lo dejo estar y a otra cosa.

    Bueno querido amigo, que tengas un feliz día de Reyes y si soluciono algo te lo comento.

    Muchas gracias como siempre querido Enrique.

    Un fuerte abrazo.

    Gemma

    viernes, 6 de enero de 2017 6:05