Я нашел изящный способ импортировать целые CSV-файлы в доступ.
Мне было поручено импортировать три CSV-файла в три таблицы для одной базы данных. Это должно было быть сделано около 100 раз, и каждый CSV будет варьироваться от 200 МБ до 500 МБ. Поскольку три схемы таблиц были одинаковыми для каждой базы данных, я потратил некоторое время, пытаясь найти лучший способ создания сценария для импорта всего этого для меня.
Я впервые использовал
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, p1, _
Application.CurrentProject.Path & "\Page1\_8_lift_base_" & dbName & ".csv",_
True, sh.Name & "!"
В большинстве случаев это работало, за исключением случаев, когда при открытии CSV появлялось приглашение «только для чтения», и импорт останавливался до его закрытия. Кроме того, CSV 300 МБ займет около 8-10 минут. Для 100 БД это не приемлемо.
В итоге я создал собственную спецификацию экспорта-импорта XML.
Sub make_import_spec(filePath As String, tableName As String, pageNum As Long)
'By Ryan Griffin
Dim name_of_spec As String
name_of_spec = "imspec" & tableName
Dim xml As String
'This xml string contains the specifications the use for that table
xml = ""
xml = xml & "<?xml version=""1.0"" encoding=""utf-8"" ?>" & vbCrLf
xml = xml & "<ImportExportSpecification Path=" & Chr(34) & filePath & Chr(34) & " xmlns=""urn:www.microsoft.com/office/access/imexspec"">" & vbCrLf
xml = xml & " <ImportText TextFormat=""Delimited"" FirstRowHasNames=""true"" FieldDelimiter="","" CodePage=""437"" Destination=" & Chr(34) & tableName & Chr(34) & " >" & vbCrLf
xml = xml & " <DateFormat DateOrder=""MDY"" DateDelimiter=""/"" TimeDelimiter="":"" FourYearDates=""true"" DatesLeadingZeros=""false"" />" & vbCrLf
xml = xml & " <NumberFormat DecimalSymbol=""."" />" & vbCrLf
xml = xml & " <Columns PrimaryKey=""{none}"">" & vbCrLf
xml = xml & " <Column Name=""Col1"" FieldName=""field1"" Indexed=""YESDUPLICATES"" SkipColumn=""false"" DataType=""Text"" Width=""12"" />" & vbCrLf
xml = xml & " <Column Name=""Col2"" FieldName=""field2"" Indexed=""NO"" SkipColumn=""false"" DataType=""Text"" Width=""16"" />" & vbCrLf
xml = xml & " <Column Name=""Col3"" FieldName=""field3"" Indexed=""YESDUPLICATES"" SkipColumn=""false"" DataType=""Text"" Width=""24"" />" & vbCrLf
xml = xml & " <Column Name=""Col4"" FieldName=""field4"" Indexed=""NO"" SkipColumn=""false"" DataType=""Text"" Width=""16"" />" & vbCrLf
xml = xml & " </Columns>" & vbCrLf
xml = xml & " </ImportText>" & vbCrLf
xml = xml & "</ImportExportSpecification>"
'By Ryan Griffin
'Now you can add the specification to the project
CurrentProject.ImportExportSpecifications.Add name_of_spec, xml
' This will run your specification and import you csv file
DoCmd.RunSavedImportExport name_of_spec
End Sub
После запуска кода с этой настройкой я смог импортировать файл размером 300 МБ всего за минуту (~ 62 секунды) и смог убедиться, что каждый столбец имеет соответствующий тип данных и правильную индексацию (без дополнительного шага). Таким образом, с помощью этого метода мне удалось добиться некоторого увеличения скорости от 7 до 9 раз, с легкостью зная, что данные будут правильными.
* Примечание: для этой функции я предоставляю путь к файлу CSV (который включает в себя name.csv), желаемое имя таблицы и pagenum, который является ссылкой на таблицу. (Я использовал это для различения таблиц. В строке xml у меня был оператор if, основанный на этом pageNum, где if pageNum = 1; добавить эти столбцы в строку).
Это будет прекрасно работать для всех ваших пожеланий по импорту CSV, если в файлах csv нет «.» (точка) в имени [помимо расширения]. Для этого вам нужно будет использовать Scripting FileSystemObject, чтобы получить файл, и изменить его имя, чтобы использовать что-то вроде подчеркивания, а не точки, перед импортом.
Я знаю, что это может быть немного затянуто, но есть очень мало ресурсов, которые являются надежными и полезными в этой области. Мне потребовался почти целый день, чтобы свести на нет варианты и разобраться в беспорядке VBA. Я надеюсь, что это может помочь любому, кто испытывает те же проблемы, что и я.