Как подключиться к именованному диапазону Excel в SQL-запросе ADODB - PullRequest
0 голосов
/ 03 января 2019

Мне нужно переместить данные из листа Excel в базу данных.Для этого я создаю ADODB Connection и могу выполнить такой запрос SQL: INSERT INTO myTable SELECT * FROM [Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb].[Shee1$A1:C100]

Моя проблема заключается в том, что диапазон не может указывать дальше 255 столбцов, то есть столбца IU.Я хочу попробовать использовать именованный диапазон, но не могу найти подходящую запись.Все найденные примеры подключаются напрямую к книге и используют либо ссылку SELECT * FROM [Sheet1$], либо SELECT * FROM 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].myRange
[Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb;Name=myRange]

, но безуспешно.

Как правильно использовать именованный диапазон здесь?Поможет ли это даже обойти ограничение числа столбцов?

Я ожидал, что [Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb].[myRange] сработает, но выдает следующую ошибку: «Механизму базы данных Microsoft Access не удалось найти объект« myRange ».Убедитесь, что объект существует (...) '

Я могу обойти его, скопировав данные из исходного листа во временный, и разместив их в пределах 255 столбцов, но было бы здорово сделать это правильно.

1 Ответ

0 голосов
/ 03 января 2019

Не уверен, что вы собираетесь найти решение для подключения к именованному диапазону. Я взглянул на то, как заставить это работать, и мне тоже не повезло, я подозреваю, что он не включен в схему после столбца 255, но может быть ошибочным.

Я подумал, что у вас также может быть эффективное решение, которое не использует циклы для добавления данных в Access. Это больше, чем просто вставка кода, но я надеюсь, что он подходит для вашей конкретной проблемы.

Мне удалось вставить ~ 2500 записей (все целые числа) примерно за 3 секунды, так что это довольно быстро.

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