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

Respuesta
2

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:

https://youtu.be/h2SSSDJx5AA

https://youtu.be/dfVlsq4ZVz8

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.


Respuesta
1

[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.

O sea que ¿El recordset obtenido desde Access lo quieren enviar a Excel? ¿Es eso?

Abraham Valencia

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.

Tu Office ¿es de 32 o 64 bits? Ojo, el office, no pregunto por el Windows.

Abraham Valencia

Buenas tardes.

Revisando mi Office, puede ver que es de 64 bits.

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.

Con las versiones de Office de 64 bits y ADO (aunque con otras cosas también) hay varios de esos "detalles" pero lo importante es que ya está solucionado.

De nada y hasta la próxima.

Abraham Valencia

Si, tienes toda la razón los "detalles" de Microsoft que te hacen dar muchas vueltas.

Pero nuevamente gracias por la asistencia.

Doy por cerrado el hilo.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas