En la nota anterior vimos como transferir datos de Excel a Access manualmente usando los mecanismos nativos de Access.
Otra alternativa es exportar los datos de Excel a Access programáticamente, es decir usando Vba.
Para nuestro ejemplo usaremos nuevamente el archivo de la nota anterior.
En la nota anterior usamos los mecanismos de Access para importar los datos de Excel.
Al realizar la tarea con Vba haremos el camino a la inversa, decir crearemos una conexión a Access desde Excel. Esto lo haremos usando objetos de la ADO library (ADO = ActiveX Data Objects).
Antes de sumergirnos en los vericuetos del código, una observación importante: para poder usar las funciones de ADO en Excel debemos primero crear una referencia con el menú Tools-Reference del editor de Vb
Como en el ejemplo anterior, empezamos por crear una base de datos que contiene una tabla a la cual queremos exportar los datos de Excel. Nuestra base de datos (bd1.mdb) contiene la tabla Ventas que por ahora está vacía
Sin entrar demasiado en detalles técnicos, podemos describir la tarea de la siguiente manera:
# - creamos una conexión a la base de datos
#- definimos en qué tabla de la base de datos queremos poner los datos
# - definimos un objeto que contenga los datos a transferir (recordset)
# - definimos donde se encuentran los datos a transferir (en nuestro ejemplo el cuaderno tiene dos hojas con datos)
# - transferimos los datos
He agregado la hoja Parámetros en la cual podemos definir donde se encuentra la base de datos, cuál es la tabla a la cual queremos copiar los datos y en qué cuaderno se encuentran. De esta manera, podemos controlar los parámetros del código con facilidad.
Como ven he agregado también la línea a partir de la cual hay que transferir los datos de la hoja. En general los datos empiezan en la fila 2 (la 1 está ocupada por los encabezamientos). También podemos elegir de qué hoja pasar los datos, con una lista desplegable en la celda B3.
El código de la macro es el siguiente
Sub ExcelaAccess_ADO()
Dim Conn As ADODB.Connection, RecSet As ADODB.Recordset
Dim fila As Long, primerFila As Integer, ultimaFila As Long, iX As Long
Dim dataSource As String, Tabla As String
Dim wsName As String
'definimos los parametros que seran usados por el codigo
dataSource = Sheets("parametros").[B1]
Tabla = Sheets("parametros").[B2]
wsName = Sheets("parametros").[B3]
primerFila = Sheets("parametros").[B4]
' establecemos la conexion a la base de datos
Set Conn = New ADODB.Connection
Conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source= " & _
dataSource & ";"
' definimos un recordset
Set RecSet = New ADODB.Recordset
RecSet.Open Tabla, Conn, adOpenKeyset, adLockOptimistic, adCmdTable
ultimaFila = WorksheetFunction.CountA(Sheets(wsName).Range("A:A"))
For iX = primerFila To ultimaFila 'mientras que la celda la columna A
'tenga un valor transferimos la fila
With RecSet
.AddNew
.Fields("Factura") = Sheets(wsName).Cells(iX, 1).Value
.Fields("Fecha") = Sheets(wsName).Cells(iX, 2).Value
.Fields("Producto") = Sheets(wsName).Cells(iX, 3).Value
.Fields("Descripcion") = Sheets(wsName).Cells(iX, 4).Value
.Fields("Cantidad") = Sheets(wsName).Cells(iX, 5).Value
.Fields("Precio") = Sheets(wsName).Cells(iX, 6).Value
.Fields("Total") = Sheets(wsName).Cells(iX, 7).Value
.Update
End With
Next iX
RecSet.Close
Set RecSet = Nothing
Conn.Close
Set Conn = Nothing
End Sub
Este código debe ponerse en un módulo común de Vba.
Hola Buenas Tardes..Muy bueno tu codigo pero me gustaria saber como esta dispuesto en excel y en access lo que estas transfiriendo porque estoy tratando de ahcer lo mismo y no he podido...
ResponderBorrarAgradeceria mucho tu ayuda
Tal como está explicado en la nota. ¿Qué es lo que no te sale?
ResponderBorrartengo una duda el codigo cuando se exportan los datos a la hora de crear un nuevo registro este lo superpone al anterior o lo crea en el orden que se lleva
ResponderBorrarLos registros se van agregando.
ResponderBorrarHola yo estoy tratando de hacer lo mismo, estuve buscando la forma y encontre lo que has publicado, yo estoy trabajando con access, el codigo que pusiste lo puse en un modulo asi como lo indicas, pero al momento de correrlo me muestra el siguiente error:
ResponderBorrarError de compilación
Sub o función no definida
Me podrías ayudar por favor
¿Has creado la referencia a la ActiveX Data Objects Library cono está indicado al principio de la nota?
ResponderBorrarHola soy Azul.
ResponderBorrarYo estoy buscando la froma de pasar un excel a access y vi lo que has publicado, estoy probando tu codigo, pero tengo unas dudas, lo que pones como sheets es el nombre de la hoja de excel en donde se encuetran los datos a pasar
Azul,
ResponderBorrarsi te refieres a Sheets(wsName), la variable wsName contiene el nombre de la hoja con los datos que hemos definido con
wsName = Sheets("parametros").[B3]
donde la celda B3 de la hoja "parametros" contiene el nombre de la hoja ("abril" en nuestro ejemplo).
Buenas tardes,
ResponderBorrarEstoy intentando hacer este ejercicio y creo que no me encuentra donde tengo guardad la excel ventas_access_vba el compilador falla con el error de "error en el método sheets" cuando le doy a depurar me marca: dataSource = Sheets("parametros").[B1]
¿La hoja "parametros" existe en tu modelo?
ResponderBorrarMuchas gracias Jorge, excelente ejemplo, justo lo que estaba buscando.
ResponderBorrarRealicé tu ejercicio, y está bien estructurado.
Para estos ejercicios es importante aclarar a los usuarios que requieren conocimientos basicos de base de datos asi como programación en VBA.
Fuera de ello, todo esta super bien, muchas gracias por compartirnos tus conocimientos.
Estimado,
ResponderBorrargracias por el codigo. Sabes, estoy usando Access 2007 y al pasar por el reconocimiento de la base de datos, me arroja un error, el que indica que no reconoce el formato de la base de datos.
me podrias ayudar?
agradecido
Muchas gracias jorge, el ejemplo esta buenisimo.
ResponderBorrartengo una duda. pues estoy ocupando Access 2007 y me arroja un error que no reconoce el formato de la tabla de datos. en el ejemplo es mdb y las que uso son accdb. sabes por donde puedo corregir ese detalle?.
agradecido
Releyendo el comentario, reemplazar el código
ResponderBorrarConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source= " & _
dataSource & ";"
por
Conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source= " & _
dataSource & ";"
Funciono Perfecto.
ResponderBorrarmuchas gracias
Buenas noches. Antes que nada me parece excelente tu blog.
ResponderBorrarAhi va mi pregunta, me sale el siguiente error:
"error 3706: no se encontro el proveedor especificado".
Los pasos arriba detallados los segui todos, tenes idea que puede estar pasando?
Gracias.
Matias
Matías,
ResponderBorrar¿qué versión de Excel estás usando?
El proveedor a que se refiere el mensaje es Microsoft.Jet.OLEDB.4.0 (fijate en el comentario del 9/12/2012 también). Parece ser que no tenés alguna de esas versiones.
Jorge, que buen aporte, con unas adecuaciones a mi proyecto funciona de maravilla.
ResponderBorrarMuchas Gracias.
ATTE. David
Jorge no me resulta con excel 2010, alguna ayuda
ResponderBorrarTenés que reemplazar la orden
ResponderBorrarProvider=Microsoft.Jet.OLEDB.4.0
con
Provider=Microsoft.ACE.OLEDB.12.0
Muy buen informacion pero me sale un error y dice esto "Error de sintaxis en la clausula From
ResponderBorrarERROR EN LA SNTAXIS DE LA CLAUSULA FROM.
ResponderBorrarME MANDA A ESTE RENGLON:
Set RecSet = New ADODB.Recordset
RecSet.Open Tabla, Conn, adOpenKeyset, adLockOptimistic, adCmdTable
¿Has creado la referencia a la ADO library, como se muestra en la primer parte de la nota? ¿Has modificado los parámetros para que apunten a la hoja y a las celdas adecuadas?
ResponderBorrarhola que tal te consulto. como se puede hacer para que me actualize los datos desde access y me elimine los existentes dado que me los va agregando y solo quiero que actualice los mismos.
ResponderBorrarEj. Cliente 1000 compro 2300 el martes a las 9 de la mañana
a la tarde este cliente 1000 compro 2300 mas,cuando actualizo no me deja dado que la base de acces no se deja poner datos por duplicado
Disculpas por la demora. No me queda claro lo que querés hacer. En la base de datos hay un registro del cliente 1000 con 2300 en ventas. ¿Ahora hay que actualizarlo a 4600? Si es así, ¿no querías registrar las ventas por fecha/hora? Me parece extraño lo de los duplicados ya que si bien es el mismo cliente los datos son distintos (fecha/hora, contidad, importe).
ResponderBorrarJorge gracias por el código, pero quisiera saber lo siguiente:
ResponderBorrarTengo una tabla con un campo Primary Key, importo el excel a access mediante código VB6 y hasta ahí me funciona muy bien.
Lo que quiero saber es como hago para importar datos de dos columnas de excel a dos columnas específicas de la misma tabla access sin borrar los registros existentes en las demás columnas de la misma tabla.
Muchas gracias por tu respuesta
Atte, Douglas
Hola Douglas, ¿se trata de corregir registros existentes?
ResponderBorrarJorge gracias por tu pronta respuesta. Esa tabla maneja 2 campos o columnas que mes a mes debo actualizar pues deben contener unos pagos y la fecha de pago, digamos que si podría ser corregis registros existentes porque los campos pago y fechapago los debo modificar mes a mes
ResponderBorrarTrabajo con Ado
Lo he tratado de hacer de la siguiente manera:
Set Cn = New ADODB.Connection 'Ajusta Cn como conexión ADO con BD
Set Rs = New ADODB.Recordset 'Ajusta Rs como recordset ADO con BD
Set ArchivoExcel = New Excel.Application
Cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & "Data Source=" & path + nombrebasedatos + ";"
Rs.ActiveConnection = Cn
Rs.CursorLocation = adUseClient
Rs.LockType = adLockOptimistic
Rs.Open "Select * From DatosPersonalesCartera"
For x = 2 To 253
With Rs
.Requery
.AddNew
!apto = ArchivoExcel.Cells(x, 2) 'este es Primary Key
!pago = ArchivoExcel.Cells(x, 16) 'estos son lo campos que debo importar a la tabla mes a mes
!fechapago = ArchivoExcel.Cells(x, 17) 'y están ubicados en la columna 2, 16 y 17 de la tabla
.Update
End With
La verdad es que tengo problemas porque cuando ejecuto la aplicación me sale error en la primary key porque se duplica el índice; y de otro lado no me importa los datos.
Gracias por tu ayuda.
Douglas, te sugiero que, si no lo has hecho, pongas tu consulta en alguno de los foros de Access. En estos días, lamentablemente, no dispongo de tiempo libre para ocuparme de consultas específicas.
ResponderBorrarbuen día:
ResponderBorrarPresento un problema en la siguiente sentencia RecSet.Open Tabla, Conn, adOpenKeyset, adLockOptimistic, adCmdTable , el error que muestra es "Argumentos incorrectos, fuera del intervalo permitido o en conflicto con otros
Tal como dice la información del error, tienes que revisar los argumentos, en particular la variable Tabla.
ResponderBorrarBuenas tardes,
ResponderBorrarSe para aquí:
Conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source= " & _
dataSource & ";"
¿Hay alguna actualizacón posterior?
Fijate en esta página
ResponderBorrarhttps://www.connectionstrings.com/excel/
Buenas tardes,
ResponderBorrarobservo que en ningún momento se establece la ruta del excel que se va a cargar a access, y sin embargo la hoja si.
en mi caso voy a hacer que VBA abra todos los excel contenidos en una carpeta y repita el proceso para cada uno de ellos, siendo todos iguales, y cargándolos a una tabla de access.
Mi primera duda es si al cargar un archivo tras otro no estará pisando las líneas de la tabla del access cargadas con el excel anterior.
La segunda duda es cómo establezco en que carpeta debe buscar el excel para ya encargarme yo de que busque todos los archivos de esa carpeta.
Un saludo
Muchas gracias previamente.
Hola, fijate en la tercera nota sobre el tema.
ResponderBorrar