Tested in Excel 365 (16.8730.2046) 64-bit. All links open in new tab.
More info here
- Option Explicit
- Public objConnection As Connection
- Public objRecordset As Recordset
- Public Function RangeToRecordset(ExcelFile As String, StrSQL As String, Optional HasHeader = "Yes") As Recordset
- ' need to add the following reference:
- ' Microsoft ActiveX Data object...
- Const adOpenStatic = 3
- Const adLockOptimistic = 3
- Const adCmdText = &H1
- Set objConnection = CreateObject("ADODB.Connection")
- Set objRecordset = CreateObject("ADODB.Recordset")
- objConnection.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
- "Data Source=" & ExcelFile & ";" & _
- "Extended Properties=""Excel 8.0;HDR=" & HasHeader & ";"";"
- objRecordset.Open StrSQL, _
- objConnection, adOpenStatic, adLockOptimistic, adCmdText
- Set RangeToRecordset = objRecordset
- End Function
- Public Function CloseConnectionAndRecordset(Optional cn As Connection, Optional rs As Recordset)
- If IsMissing(cn) Then Set cn = objConnection
- If IsMissing(rs) Then Set rs = objConnection
- Set cn = Nothing
- Set rs = Nothing
- End Function
You can use it like this:
- Sub main()
- Dim rs As Recordset
- Dim i, FieldNames
- Set rs = RangeToRecordset(ActiveWorkbook.FullName, "select * from [" & ActiveSheet.Name & "$]")
- ' do something with the recordset:
- ' get header
- For i = 0 To rs.Fields.Count - 1
- FieldNames = FieldNames & rs.Fields(i).Name & "|"
- Next i
- ' paste header
- Range(Cells(1, 13), Cells(1, rs.Fields.Count + 13)).Value = Split(FieldNames, "|")
- ' paste data
- Range("M2").CopyFromRecordset rs
- Debug.Print rs.RecordCount, rs.Fields.Count
- ' free memory
- CloseConnectionAndRecordset objConnection, objRecordset
- End Sub