Reputation: 410
I need to move data from Excel sheet to database. To do this, I create ADODB Connection and I am able to execute such an SQL query:
INSERT INTO myTable SELECT * FROM [Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb].[Shee1$A1:C100]
My problem is that the range cannot point further than 255 columns, i.e. column IU. I want to try using named range instead, but I cannot find suitable notation. All examples I found connect directly to the workbook, and use either SELECT * FROM [Sheet1$]
reference, or SELECT * FROM myRange
as an example of named range. I tried things like
[Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb].[myRange]
[Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb].[myRange$]
[Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb].myRange
[Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb;Name=myRange]
, but without success.
What is the proper way to use named range here? Would it even help working around column number limitation?
I expected [Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb].[myRange]
to work, but it throws the following error: 'The Microsoft Access database engine could not find the object 'myRange'. Make sure the object exists (...)'
I can work it around by copying data from source sheet to temporary one, and have it within 255 column limit, but it would be great do it right way.
Upvotes: 3
Views: 4278
Reputation: 31
I found this link sql on range
I have tested most of the examples without any issues. I will add a new one working also a sheet named range
strQuery = “SELECT * FROM [Sheet1$mynamedrange]“
Upvotes: 0
Reputation: 31
I had the same issue and the solution is pretty easy, even though it works only for named ranges at Workbook level. The connection has to be done to the Workbook (i.e. [Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb]). Then in the Query just type: SELECT * FROM [myRange] (Please note the square brackets and the absence of $ sign)
Upvotes: 1
Reputation: 1
You need to use a construction:
[Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb].[$myRange]
Upvotes: 0
Reputation: 5677
Not sure if you are going to find a solution for connecting to a named range. I took a look at getting this to work, and I had no luck either, I suspect it's not included in the schema past 255 column, but could be wrong.
I thought you might as well have an efficient solution that doesn't rely on looping for adding data to Access. It's more code than just doing an insert, but I hope it fits your specific problem.
I was able to do an insert of ~2500 records (all integers) in about 3 seconds, so it is fairly quick.
Option Explicit
Private Function GetDisconnectedRecordset(TableName As String) As ADODB.Recordset
Dim conn As ADODB.connection: Set conn = getConn()
Dim rs As ADODB.Recordset: Set rs = New ADODB.Recordset
With rs
.CursorLocation = adUseClient ' <-- needed for offline processing
'Get the schema of the table, don't return anything
.Open "Select * from " & TableName & " where false", conn, adOpenDynamic, adLockBatchOptimistic
End With
rs.ActiveConnection = Nothing
conn.Close
Set conn = Nothing
Set GetDisconnectedRecordset = rs
End Function
'Do an update batch of the data
'Portion used from: https://stackoverflow.com/questions/32821618/insert-full-ado-recordset-into-existing-access-table-without-loop
Sub PopulateDataFromNamedRange()
Dim conn As ADODB.connection
Dim ws As Excel.Worksheet: Set ws = ThisWorkbook.Worksheets("Sheet2") 'Update to your sheet/wb
Dim NamedRange As Excel.Range: Set NamedRange = ws.Range("Test") ' Update to your named range
Dim NamedItem As Excel.Range
Dim rs As ADODB.Recordset: Set rs = GetDisconnectedRecordset("[TestTable]") 'Specify your table name in access
Dim FieldName As String
Dim Row As Long
Dim AddRow As Long
'Add Data to the disconnected recordset
For Each NamedItem In NamedRange
If Not NamedItem.Row = 1 Then
Row = NamedItem.Row
If Not Row = AddRow Then rs.AddNew
AddRow = NamedItem.Row
FieldName = ws.Cells(NamedItem.Row - (NamedItem.Row - 1), NamedItem.Column).Value
rs.Fields(FieldName).Value = NamedItem.Value
End If
Next
'Connect again
Set conn = getConn()
Set rs.ActiveConnection = conn
rs.UpdateBatch '<-- 'Update all records at once to Access
conn.Close
End Sub
Private Function getConn() As ADODB.connection
Dim conn As ADODB.connection: Set conn = New ADODB.connection
conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Ryan\Desktop\Example.accdb"
Set getConn = conn
End Function
Upvotes: 1