Reputation: 24077
OK so I have this function which queries a database using a query string that I pass to it. At the moment it outputs the query result in the worksheet. How do I just get the function to give me the result as a range that I can use in VBA to perform calculations etc? How would I then reference this range? E.g. to get the "Name" column in the result.
Function Access_Data(query As String)
'Requires reference to Microsoft ActiveX Data Objects xx Library
Dim Cn As ADODB.Connection, Rs As ADODB.Recordset
Dim MyConn, sSQL As String
Dim Rw As Long, Col As Long, c As Long
Dim MyField, Location As Range
'Set destination
Set Location = Sheets(1).Range("a1")
'Set source
MyConn = "S:\Docs\Harry\Engine Client\Engine3.accdb"
'Create query
sSQL = query
'Create RecordSet
Set Cn = New ADODB.Connection
With Cn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.Open MyConn
Set Rs = .Execute(sSQL)
End With
'Write RecordSet to results area
Rw = Location.Row
Col = Location.Column
c = Col
Do Until Rs.EOF
For Each MyField In Rs.Fields
Cells(Rw, c) = MyField
c = c + 1
Next MyField
Rs.MoveNext
Rw = Rw + 1
c = Col
Loop
Set Location = Nothing
Set Cn = Nothing
End Function
Upvotes: 1
Views: 6818
Reputation: 311
Function Access_Data(query As String)
'Requires reference to Microsoft ActiveX Data Objects xx Library
Dim Cn As ADODB.Connection, Rs As ADODB.Recordset
Dim MyConn, sSQL As String
Dim Rw As Long, c As Long
Dim MyField, Result
'Set source
MyConn = "S:\Docs\Harry\Engine Client\Engine3.accdb"
'Create query
sSQL = query
'Create RecordSet
Set Cn = New ADODB.Connection
With Cn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.CursorLocation = adUseClient
.Open MyConn
Set Rs = .Execute(sSQL)
End With
'Write RecordSet to results
Redim Result(1 To Rs.RecordCount, 1 To Rs.Fields.Count)
Rw = 1
Do Until Rs.EOF
c = 1
For Each MyField In Rs.Fields
Result(Rw, c) = MyField
c = c + 1
Next MyField
Rs.MoveNext
Rw = Rw + 1
Loop
Set Cn = Nothing
Access_Data = Result
End Function
This will return a multi-dimension array. A range must refer to some portion of a worksheet: you cannot create an "invisible" range. (Though you can make a portion of a worksheet invisible, if that's what you're after.)
To access the results:
Dim v, i As Long
v = Access_Data("select ID, Name from somewhere")
For i = 1 To UBound(v, 1)
MsgBox v(i, 1) & " / " & v(i, 2)
Next
Upvotes: 1
Reputation: 14053
Sample how to read data from SQL Server and the result insert into worksheet (here using integrated security). If the target sheet was empty before inserting new data then use UsedRange property to reference it. Or calculate it, rng is the top most left cell.
Option Explicit
' Add reference to Microsoft ActiveX Data Objects Lib
Public Sub main(): On Error GoTo Err_handler
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
cn.ConnectionString = "Provider=SQLOLEDB;Data Source=MYSUPERSERVER;Initial Catalog=MYSUPERDATABASE;Integrated Security=sspi"
cn.Open
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.ActiveConnection = cn
rs.Open "SELECT * FROM MyTable"
Dim fld As ADODB.Field
Dim rng As Range
Set rng = [a1]
For Each fld In rs.Fields
rng.Value = fld.Name
Set rng = rng.Offset(0, 1)
Next fld
Set rng = rng.Offset(1, -rs.Fields.Count)
rng.CopyFromRecordset rs
rs.Close
cn.Close
Set rs = Nothing
Set cn = Nothing
Exit Sub
Err_handler:
MsgBox Err.Description
End Sub
Upvotes: 1