Importar anexando registros desde una tabla externa a otra

Se me ha planteado un problema.

Quiero importar los registros de una tabla que esta en un archivo mdb externo a una tabla en otro archivo de access mdb (que tendría abierto) anexando los registros que importo a los ya existentes.

Lo mas cercano que he llegado es con:

DoCmd. TransferDatabase acImport, "Microsoft Access", "c:\DatosSendSmS.mdb", acTable, "DatosUsuarioSendSMS", "SendSMS", False

Pero lo que me hace es una nueva tabla y eso no es lo que necesito.

Los registros de la tabla DatosUsuarioSendSMS se tienen que añadir a los ya existentes en la tabla SendSMS que corresponde a la db desde la cual se importan los datos en cuestión.

Tengo una version previa que anexaba perfectamente los registros desde un archivo de texto:

DoCmd. TransferText acImportFixed, "SendSMS - Especificación de exportación", "SendSMS", "C:\SendSMS-ancho-fijo.txt", True, ""

Pero el problema radica en que el archivo MDB en cuestión es controlado por un software que cada cierto tiempo lo modifica de tal modo que aunque la importación del archivo de texto funciona después no se producen los efectos esperados.

Mas concretamente los datos importados a la tabla no se borran, que seria el comportamiento normal, cuando le correspondería hacerlo y por alguna razón relativa a dicho software el proceso no se desarrolla como debiera (según los logs).

En las pruebas me he dado cuenta de que el archivo de "especificación de exportación" no funciona como debiera y se me ha ocurrido que el problema puede estar ahí, aunque access no se queje.

En otras palabras. Tengo un formulario que se ejecuta automáticamente al abrir la DB y funciona ok. Hace la importación etc.

Cuando el software modifica la db cada tantos días el proceso de dicho software con la db falla.

Si creo otro archivo de "especificación de exportación" en ese nuevo archivo entonces funciona.

A saber que el MDB no cambia de nombre y conserva los valores almacenados en las otras tablas día tras día.

¿Hay alguna opción?

1 Respuesta

Respuesta
1

Prueba por medio de una SQL de datos anexados:

Private Sub Form_Load()

Dim rutaBDExt As String

Dim miSql As String
rutaBDExt = "C:\DatosSendSmS.mdb"
miSql = "INSERT INTO SendSMS SELECT * FROM DatosUsuarioSendSMS IN '" & rutaBDExt & "'"
DoCmd.SetWarnings False
DoCmd.RunSQL miSql
DoCmd.SetWarnings True
MsgBox "Anexión realizada correctamente", vbInformation, "OK"
End Sub

Es decir: INSERT INTO <nombreTabla> SELECT <campos a anexar> FROM <nombreTablaExterna> IN '<rutaBDExterna>'

Lo de los setwarnings es para que no salga el mensaje de access de "se va a anexar..."

El Msgbox lo puedes dejar, quitar, según tus necesidades, yo lo puse para que avise de que se realizó la operación.

El código lo he puesto en el evento Al Cargar del Formulario.

Ahora me surge una pregunta. Lo que comentas de: "Mas concretamente los datos importados a la tabla no se borran, que seria el comportamiento normal, cuando le correspondería hacerlo..." ¿Quieres decir que después de anexar los datos a la BD, los registros de la BD original se tienen que borrar?

Si la respuesta es sí, el código podría ser este:

Dim rutaBDExt As String
Dim miSql As String
Dim DBExt As Database
Dim reg As Recordset
rutaBDExt = "C:\DatosSendSmS.mdb"
miSql = "INSERT INTO SendSMS SELECT * FROM DatosUsuarioSendSMS IN '" & rutaBDExt &
DoCmd.SetWarnings False
DoCmd.RunSQL miSql
DoCmd.SetWarnings True
MsgBox "Anexión realizada correctamente", vbInformation, "OK"

Set DBExt = OpenDatabase(rutaBDExt)
Set reg = DBExt.OpenRecordset("DatosUsuarioSendSMS", dbOpenTable)
reg.MoveFirst
Do Until reg.EOF
reg.Delete
reg.MoveNext
Loop
MsgBox "Datos borrados en Tabla original", vbInformation, "OK"

La segunda parte (la de borrar) también la puedes hacer con SQL:

Dim rutaBDExt As String
Dim miSQL As String
rutaBDExt = "C:\DatosSendSmS.mdb"
miSQL = "INSERT INTO SendSMS SELECT * FROM DatosUsuarioSendSMS IN '" & rutaBDExt & "'"
DoCmd.SetWarnings False
DoCmd.RunSQL miSQL
MsgBox "Anexión realizada correctamente", vbInformation, "OK"

miSQL = "DELETE FROM DatosUsuarioSendSMS IN " & rutaBDExt & "'"
DoCmd.RunSQL miSQL
DoCmd.SetWarnings True

MsgBox "Datos borrados en Tabla original", vbInformation, "OK"

Hola, buen día,

Genial la respuesta. No se me había ocurrida, lógicamente porque de sql no tengo ni papa.

Sobre tu pregunta, el software que maneja el archivo MDB carga cierta información en la tabla que tratamos (en la que importamos registros) hace las cosillas para lo que esta programado y después borra todos los registros de dicha tabla.

Entonces, el problema es que si bien continua cargando en la tabla esa cierta información y efectivamente la borra, la que importamos anexandola desde el archivo de texto ni la trata ni la borra. El procedimiento normal es que borre todo el contenido de la tabla y así lo hace por un tiempo, pero como comento cada tantos días hace "algo" con el MDB y a raíz de eso empieza a dejar los eregistros importados en la tabla.

Bueno, a la vista de la valiosa información que me muestras se me ocurre un modo mas limpio de hacerlo que seria desde el mismo archivo mdb donde están los registros a importar ejecutar el código correspondiente y exportar dichos registros anexandolos a la tabla en cuestión.

Imagino que se trataría de cambiar esto:

miSql = "INSERT INTO SendSMS SELECT * FROM DatosUsuarioSendSMS IN '" & rutaBDExt &

por lo que correspondiera.

Estoy en lo cierto?

Lo ejecutaría desde un formulario automáticamente al abrir la DB, la cual llamaría programando la tarea con el programador de tareas de windows. Seria un proceso automático y desatendido.

Ya tengo el procedimiento para cerrar el formulario, db, etc. que es el he usado hasta ahora y funciona ok.

De este modo no tocaría para nada el archivo original desde el que se manejan todos los datos (salvo la importación de registros, claro) y creo que estaría mas seguro a la hora de evitar interferir con el software que lo maneja.

Solo me resta una duda.

El primer campo de la DB es autonumérico y es clave principal. Me gustaría que los registros que anexo se añadieran a partir del primer registro vacío (que así lo hacen) pero comenzando en el siguiente numero usable.

La tabla que importo tiene una numeraion correlativa que le pongo yo, si, pero no se corresponde con el numero del primer registro disponible, que no se cual puede ser a menos que la abra a mano y lo mire, pero claro aquí ya no habría proceso automatico.

Si esto se pudiera hacer que pasaría con dicho campo en la tabla a importar?.

Se dejaría sin contenido o algo así?

Bueno, disculpa el rollazo,

Un montón de gracias,

Saludos!

PD: Si se te ocurre algo mas limpio adelante por favor

Si el procedimiento lo vas a hacer desde la BD origen, tendrías que cambiar el código un poco más

La SQL sería de este modo: INSERT INTO <tablaDestino> IN '<rutaBDExterna>'
SELECT nomTabla.nomCampo1,...,nomTabla.nomCampoN FROM nomTabla

Ahora rutaBDExterna sería la BD donde vas a exportar.

Dim rutaBDExt As String
Dim miSQL As String
rutaBDExt = "dirección de la BD Destino .mbd"
miSQL = "INSERT INTO SendSMS IN '" & rutaBDExt & "' SELECT * FROM DatosUsuarioSendSMS"
DoCmd.SetWarnings False
DoCmd.RunSQL miSQL
MsgBox "Anexión realizada correctamente", vbInformation, "OK"
miSQL = "DELETE FROM DatosUsuarioSendSMS"
DoCmd.RunSQL miSQL
DoCmd.SetWarnings True
MsgBox "Datos borrados en Tabla original", vbInformation, "OK"

Lo del autonumérico te lo digo más tarde, que no esty en el ordenador y lo quiero comprobar antes de darte una respuesta.

Buff, lo de los números correlativos de los registros no lo pille, pero te comento un par de cosas, por si te sirve de ayuda:

1º/ Al importar/exportar con SQL, si el número de la tabla origen coincide con uno de los autonuméricos de la de destino no te va a importar ese registro. Si el número de la TOrigen es mayor que el autonumérico, te importa esos números, con lo que te quedará un salto en el el autonumérico de la TDestino.

2º/ Si el número de la TOrigen no te interesa guardarlo, y que en TDestino se siga la numeración correlativa (del último valor del autonumérico, si ya tienes huecos, estos se quedan ahí...), te doy la opción de anexar y borrar por DAO:

Código para la BDOrigen

Dim rutaBDExt As String
Dim DBOrigen As DAO.Database
Dim DBDestino As DAO.Database
Dim RegOrig As DAO.Recordset
Dim RegDest As DAO.Recordset
rutaBDExt = "Ruta DBDestino.mdb"
Set DBOrigen = CurrentDb
Set DBDestino = OpenDatabase(rutaBDExt)
Set RegOrig = DBOrigen.OpenRecordset("NombreTablaOrigen", dbOpenDynaset)
Set RegDest = DBDestino.OpenRecordset("NombreTablaDestino", dbOpenDynaset)
RegOrig.MoveFirst
Do Until RegOrig.EOF
RegDest.AddNew
RegDest("campo1") = RegOrig("campo1")
RegDest("campo2") = RegOrig("campo2")
(... y así con todos, menos el autonumérico)
RegDest.Update
RegOrig.MoveNext
Loop
RegDest.Close
MsgBox "Anexión realizada correctamente", vbInformation, "OK"
RegOrig.MoveFirst
Do Until RegOrig.EOF
RegOrig.Delete
RegOrig.MoveNext
Loop
MsgBox "Datos borrados en Tabla original", vbInformation, "OK"

RegOrig.Close

DBOrigen.Close

DBDestino.Close

Set DBOrigen=Nothing

Set DBDestino=Nothing

Si el código lo pones en la BD que recibe los datos, cambia por esto:

Set DBOrigen = OpenDatabase(rutaBDExt)
Set DBDestino = CurrentDb

Ok. Lo voy a probar y te comento. No necesito borrar los registros ni del origen ni del destino a menos me siga dando problemas al no borrarlos el propio software.

Creo que me puedo apañar con el codigo.

Se me paso un detalle importante y es que la maquina corre access 2000.

Supongo que el codigo es compatible, si no pronto lo averiguare.

Lo de el orden correlativa, disculpa si no me explique bien:

En la tabla que yo creo e importo tengo un campo que se corresponde con el autonumerico de destino y este campo en mi tabla origen tiene orden correlativo (igual el termino no es el correcto) U sea, numerado del 30 al 60 de uno en uno.

Por lo que veo ya no necesito ese campo en la tabla fuente, no es asi?

Mas gracias :-)

Saludos.

Hola,

Me funciona ok en las pruebas (he tenido que habilitar DAO) pero al ponerlo en la maquina en cuestión, que como decía corre access 2000 me da este error:

"Se produjeron 1 errores cuando se cargo el formulario o informe.

Cargo un formulario o informe que contiene controles o propiedades que MS Access no reconoce y serán ignoradas"

He metido el código en un formulario para que se ejecute al iniciar la DB en:

Private Sub Form_Load()

Si intento abrirlo en vista diseño me da el mismo error.

Se puede hacer algo?

Muchas gracias, perdona por los inconvenientes.

Saludos.

Hola, buenas,
Lo he solucionado cambiando el código de :
Private Sub Form_Load()
a
Form_Open(Cancel As Integer)
Y
de momento parece funcionar ok a la espera ver si desaparecen los
problemas relacionados con el soft. Lo sabre en varias horas.
Muchas gracias, tu código funciona perfectamente.
Saludos.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas