Ejecutar consulta a SQL Server desde Access
Esta tarde nuevamente me dirijo a ustedes, para pedir de su ayuda.
Quizá sea una pregunta bastante repetida, pero no he encontrado una respuesta concreta a mi pregunta.
La pregunta, es: ¿Cómo puedo desde un formulario en Access ejecutar y extraer información en una tabla que esta en SQL Server?.
He encontrado mucha información para hacer esto, desde Excel, pero no he encontrado una respuesta clara para hacerlo desde Access, el objetivo es hacerlo todo desde código, y conectarme a través de codigo directamente sin DNS, ni tablas linqueadas.
Me ayudan
2 respuestas
Para conertarte directamente a una BD en SQL Server, necesitas usar recordsets desconectados con ADO.
Yo no soy experto en ese tema (ADO), pero la idea es crear la cadena de conexión ODBC, abrir la conexion y luego abrir el recordset para trabajar con los datos.
Te dejo unos enlaces para que veas el proceso:
En estos dos vídeos del grupo de usuarios Access España, explican el uso de ADO para acceder a datos:
En ninguno se conecta a un SQL Server, pero la idea es la misma, con la cadena de conexión adecuada.
En esta web https://www.connectionstrings.com/ encontrarás cómo hacer las cadena de conexión
En este otro vídeo https://youtu.be/KUchHPkvqjQ, se muestra como trabajar con Access contra una BD MySQL con recordsets desconectados. De nuevo no se conecta a un SQL Server, pero verás que el proceso es el mismo.
DE todas formas, tmabién comentarte que la forma de conectar un Excel a un SQL Server con ADO es prácticamente la misma que hacerlo desde Access.
Un saludo.
- Compartir respuesta
[Hola
Por ejemplo, para conectarme a SQLExpress (sin clave), yo hago esto (Access 2013 64 bits):
Private Sub Form_Open(Cancel As Integer) Dim cn As ADODB.Connection Dim rst As ADODB.Recordset Dim sql As String Set cn = New ADODB.Connection cn.Open "Driver={SQL Server};" & _ "Server=ABRAHAMLAPTOP\SQLEXPRESS;" & _ "Database=Pruebas;" & _ "Uid=;" & _ "Pwd=" Set rst = New ADODB.Recordset sql = "Select * From Mitabla" With rst .CursorLocation = adUseClient .CursorType = adOpenKeyset .LockType = adLockOptimistic .Open sql, cn, , , adCmdText End With Me.Listbox1.ColumnCount = 5 Set Me.Listbox1.Recordset = rst End Sub
Como ves, mi BD se llama "Pruebas", la tabla "Mitabla" y tiene cinco campos, mostrando todos los registros en el "Listbox1".
Saludos]
Abraham Valencia
Muchas gracias.
Me ha servido enormemente, de hecho ya probé y me ha funcionado.
Una pregunta: Como puedo enviar este "rst" a un archivo de Excel, es decir exportarlo en vez de llevarlo a un "Listbox".
Me ayudas por favor.
Buenas noches.
Es correcto Abraham.
El objetivo es hacer una serie de consultas de varias tablas y después enviarlo a un Excel.
Me ayudas por favor.
Esto:
Sub SQLAccessExcel() Dim cn As ADODB.Connection Dim rst As ADODB.Recordset Dim sql As String Dim MiarchivoXl As Excel.Workbook Dim xlApp As Excel.Application Dim nCampos As Integer, x As Integer Dim nRegistros&, y As Long Set cn = New ADODB.Connection cn.Open "Driver={SQL Server};" & _ "Server=ABRAHAM-PC\SQLEXPRESS;" & _ "Database=PruebaSQLServer;" & _ "Uid=;" & _ "Pwd=" Set rst = New ADODB.Recordset sql = "Select * From Datos" With rst .CursorLocation = adUseClient .CursorType = adOpenKeyset .LockType = adLockOptimistic .Open sql, cn, , , adCmdText End With Set xlApp = CreateObject("Excel.Application") Set MiarchivoXl = xlApp.Workbooks.Add Let nCampos = rst.Fields.Count - 1 For x = 0 To nCampos MiarchivoXl.Worksheets(1).Cells(1, x + 1) = rst.Fields(x).Name Next x Let nRegistros = rst.RecordCount rst.MoveFirst For y = 1 To nRegistros For x = 0 To nCampos MiarchivoXl.Worksheets(1).Cells(y + 1, x + 1) = rst.Fields(x).Value Next x rst.MoveNext Next y xlApp.Visible = True MsgBox "Todo listo" cn.Close Set rst = Nothing: Set cn = Nothing Set MiarchivoXl = Nothing: Set xlApp = Nothing End Sub
Espero se entienda
Saludos]
Abraham Valencia
Buenas tardes.
He estado revisando tu código, considero es un código entendible.
Tengo un error, y te lo comparto:
Dim cn As Object Dim rst As Object Dim sql As String Dim MiarchivoXl As Object Dim xlApp As Object 'Excel.Application Dim nCampos As Integer, x As Integer Dim nRegistros&, y As Long Set cn = CreateObject("ADODB.Connection") Set rst = CreateObject("ADODB.Recordset") Set MiarchivoXl = CreateObject("Excel.Workbook")
En la linea de "Set MiarchivoXl = CreateObject("Excel.Workbook")", me da el siguiente error: El componente ActiveX no puede crear el archivo.
Intente activar la referencia de "Microsoft Excel 16.0 Object Library" pero nada.
Me ayudas por favor.
Estás intentando crear un objeto "Workbook" dentro del archivo de Access, lo que evidentemente no se puede. Ah, ojo, de la forma en que estás intentándolo, así creer el objeto Excel antes, te dará el mismo error. Sugiero dejarlo tal cual yo lo puse.
Abraham Valencia
Perdón.
Había cometido un error de sintaxis, te dejo el código corregido pero siempre tengo un error.
A la hora de exportar la data, únicamente me crea los encabezados pero no trae registros de la tabla.
Dim cn As Object Dim rst As Object Dim sql As String Dim xlApp As Excel.Application Dim MiarchivoXl As Excel.Workbook Dim nCampos As Integer, x As Integer Dim nRegistros&, y As Long Set cn = CreateObject("ADODB.Connection") Set rst = CreateObject("ADODB.Recordset") cn.Open "Driver={SQL Server};" & _ "Server=;" & _ "Database=;" & _ "Uid=;" & _ "Pwd=" sql = "Select * From Customer" With rst .CursorType = adOpenKeyset .Open sql, cn, , , adCmdText End With Set xlApp = CreateObject("Excel.Application") Set MiarchivoXl = xlApp.Workbooks.Add Let nCampos = rst.Fields.Count - 1 For x = 0 To nCampos MiarchivoXl.Worksheets(1).Cells(1, x + 1) = rst.Fields(x).Name Next x Let nRegistros = rst.RecordCount rst.MoveFirst For y = 1 To nRegistros For x = 0 To nCampos MiarchivoXl.Worksheets(1).Cells(y + 1, x + 1) = rst.Fields(x).Value Next x rst.MoveNext Next y xlApp.Visible = True cn.Close Set rst = Nothing: Set cn = Nothing Set MiarchivoXl = Nothing: Set xlApp = Nothing
Atte.
¿Te da un error o simplemente corre dejando los registros en blanco? De ser un error ¿en qué línea lo marca? ¿Qué error exacto te da? De ser lo segundo, agrega un:
Msgbox nRegistros
(Después de "Next x" y antes de "rst.MoveFirst" ) y comenta qué número te devuelve. Por cierto ¿estás seguro que hay registros en la tabla "Customer"?
Abraham Valencia
Buenos días.
Estoy revisando y no me da error, únicamente corre y me deja en blanco las celdas, solo exporta el encabezado de la tabla, pero no trae registros.
En el Msgbox nRegistros me muestra cero, de hecho probé con varias tablas, y no me muestra nada.
Atentamente.
Si como resultado te da cero (y no error) quiere decir que en la tabla "Customer" hay cero registros; las otras tablas que mencionas ¿también el Msgbox dio cero como resultado? ¿Son tablas tuyas o del sistema? ¿Puedes entrar a la tabla y enviar captura de pantalla de su número de registros?
Si no da error, el acceso es adecuado, el dilema no es el código.
Abraham Valencia
Buenos días Abraham.
Agradezco el apoyo que estoy teniendo de tu parte, te comento que he estado revisando el código, y te comparto, las tablas tienen información, de hecho agregue un Debug.Print rst!ID y si me permite visualizar códigos de clientes.
If Not rst.EOF Then rst.MoveFirst Do Until rst.EOF Debug.Print rst!ID rst.MoveNext Loop
Donde veo que se "pierde" o no encuentra la data, es el siguiente bloque de código.
rst.MoveFirst Let nRegistros = rst.RecordCount msgbox nRegistros For y = 1 To nRegistros For x = 0 To nCampos MiarchivoXl.Worksheets(1).Cells(y + 1, x + 1) = rst.Fields(x).Value Next x rst.MoveNext Next y
De hecho al agregar un msgbox me aparece -1.
¿Gustas que te envié el archivo de Access?.
Gracias.
Era eso:
Let nRegistros = val(rst.RecordCount)
Así se solucionará. Eso ocurre cuando usas referencias pero en realidad tienes una más actual y no es la activada. Debes haber hecho referencia a Microsoft Activex Data Object 2.5 (o inferior) y debe haber 2.8 o incluso 6.1. Si activas la más actual no será necesario usar el Val.
Abraham Valencia
Buenos dias Abraham.
Estoy probando tu observación, y puedo encontrar que con la referencia "Microsoft ActiveX Data Objects 6.1 Library" puedo ejecutar tu código sin ningún problema.
Lo raro es que sin esa referencia, aunque utilice el "VAL(rst...)" no funciona, siempre me regresa el -1, de hecho observo que con la referencia activa, no es necesario el VAL, pero sin ella no funciona de ninguna forma antes mencionada.
Agradezco el acompañamiento, creo que utilizare la referencia por temas de tiempo, solo me asegurare que todos los usuarios la tengan activa.
Nuevamente muchas gracias por tu ayuda.
- Compartir respuesta