На днях участник Djubocco сетовал в соседней теме http://www.excelworld.ru/forum/17-4539-182810-16-1460047613 , что его процедура перемещает 50 тыс. строк из Excel в Access за дикое количество времени, кажется, 167 минут?
Я не успел откликнуться, а тема уже оказалось закрытой... А товарищ Djubocco чего-то замолчал... Но мой альтруистический порыв оказался сильнее - надо ж выручить человека! - поэтому сам возобновлю разговор.
Использование библиотеки ADO в данном случае не очень удачный выбор. В Access существуют собственные, гораздо более эффективные средства экспорта/импорта.
Вот код, исполняемый в Access, которым я сегодня за 2 минуты "всосал" xlsx-файл размером 18 мегайт, содержащий 400 тыс.строк х 11 столбцов:
Sub fastImport()
Access.Application.DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12, "Лист1", "C:\...\...\MyFile.xlsx", True
End Sub
"Access.Application" указываю, чтобы было понятно, к чему привязываться, если код будет запускаться извне (из Excel или еще откуда). Внутри Access достаточно начать этот оператор с "DoCmd".
У меня аналогичный пример 12 столбцов, 400000 строк, вес файла Excel 33 мегабайта плюс вставка данных в существующую таблицу занял порядка 97 секунд. Office 2016, 64bit.
Но. И с ADODB не всё так плохо, кодом из Excel вставилось тоже самое в существующую таблицу в Access за 301 секунду
Public Sub InsertToTable()
Const lastRow = 400000, lastCol = 12
Dim pCon As New ADODB.Connection, pRSet As New ADODB.Recordset, vData As Variant
Dim k As Long, t As Single, i As Long
t = Timer: k = 0
pCon.CursorLocation = adUseClient
pCon.Open "DBQ=c:\Projects\Database2 min.accdb;Driver={Microsoft Access Driver (*.mdb, *.accdb)};DriverId=25;FIL=MS Access;MaxBufferSize=2048;PageTimeout=5;ReadOnly=0;ExtendedAnsiSQL=1;"
pRSet.CursorLocation = adUseClient: pRSet.CursorType = adOpenStatic
pRSet.Open "Select * From forImport Where FLong1 Is Null", pCon, adOpenStatic, adLockOptimistic
vData = Range("A2").Resize(lastRow, lastCol).Value
pCon.BeginTrans
For i = 1 To lastRow
k = k + 1
If (k Mod 10000) = 0 Then Debug.Print k: DoEvents
pRSet.AddNew
pRSet(0).Value = vData(i, 1)
pRSet(1).Value = vData(i, 2)
pRSet(2).Value = vData(i, 3)
pRSet(3).Value = vData(i, 4)
pRSet(4).Value = vData(i, 5)
pRSet(5).Value = vData(i, 6)
'
pRSet(6).Value = vData(i, 7)
pRSet(7).Value = vData(i, 8)
pRSet(8).Value = vData(i, 9)
pRSet(9).Value = vData(i, 10)
pRSet(10).Value = vData(i, 11)
pRSet(11).Value = vData(i, 12)
Next
pRSet.UpdateBatch: pCon.CommitTrans
pRSet.Close: pCon.Close
MsgBox Timer - t
End Sub
Так что у автора закрытого топика скорее всего были индексы в таблице Access, что и приводило к таким "тормозам".
если из экселя запустим, то как эксель узнает куда экспортировать, ну там имя базы, таблицы?
Ну, естественно, нужна предварительная подготовка. Типа CreateObject("Access.Application"), OpenDatabase и т.д. Просто открыть файл MDB или новый и писать в него (как в случае с ADO) - недостаточно, т.к. объект DoCmd доступен только в экземпляре Access.
P.S. Примерно такая минимальная болванка:
Sub runAccess()
Set acApp = CreateObject("Access.Application")
acApp.OpenCurrentDatabase strFileName
Set acDoCmd = acApp.DoCmd
acDoCmd.TransferSpreadsheet 0, 9, "Лист1", "C:\...\...\MyFile.xlsx", True
acApp.Quit
End Sub