我找到了一种将整个 CSV 导入访问的绝妙方法。
我的任务是将三个 CSV 导入单个数据库的三个表中。这必须执行大约 100 次,每个 CSV 的范围从 200MB 到 500MB。由于每个数据库的三个表模式都是相同的,我花了一些时间试图找到创建脚本来为我导入所有这些的最佳方法。
我第一次使用
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, p1, _
Application.CurrentProject.Path & "\Page1\_8_lift_base_" & dbName & ".csv",_
True, sh.Name & "!"
这适用于大多数情况,除了偶尔在打开 CSV 时会出现“只读”提示,并暂停导入直到关闭。此外,一个 300MB 的 CSV 文件大约需要 8 到 10 分钟。对于 100 个 DB,这是不可接受的。
我最终做的是创建自己的 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
使用此设置运行代码后,我能够在一分钟多一点(约 62 秒)内导入一个 300MB 的文件,并且能够确保每一列都有适当的数据类型和正确的索引(无需额外步骤)。因此,通过这种方法,我能够实现 7 到 9 倍的速度提升,并且很容易知道数据是正确的。
*注意:对于这个函数,我提供了 CSV 文件路径(包括 name.csv)、所需的表名和 pagenum,它是表引用。 (我用它来区分表。在 xml 字符串中,我有一个基于该 pageNum 的 if 语句,其中如果 pageNum 为 1;将这些列添加到字符串中)。
只要 csv 文件不包含“.”,这将非常适合您的所有 CSV 导入需求。 (句点)在名称中[除了扩展名]。为此,您需要使用 Scripting FileSystemObject 来获取文件,并在导入之前将其名称更改为使用下划线而不是句点。
我知道这可能有点啰嗦,但在该领域中可靠且有用的资源很少。我花了将近一天的时间来减少选项并整理 VBA 混乱。我希望这可以帮助那些遇到和我一样麻烦的人。