代码之家  ›  专栏  ›  技术社区  ›  Paul

访问数据项目在VBA中导入csv文件

  •  4
  • Paul  · 技术社区  · 16 年前

    我不时地遇到一个问题,我的同事开发了一个旧系统。他们往往有数千行代码来做一件简单的事情,比如导入一个csv文件。

    目前,VBA过程是:

    • 打开Excel应用程序
    • 创建新工作表
    • 填充csv文件
    • 在Excel中,将标题名称添加到文件中
    • 将工作表另存为新的Excel文件
    • 将文件导入到Access数据项目SQL表中。
    • 处理数据

    我想用它做的是:

    • 将csv导入表(如get external data函数)
    • 处理数据

    我做了一个快速的搜索,看不到任何简单的方法只是把文件吸进表格。

    任何帮助都将不胜感激。

    谢谢

    保罗

    4 回复  |  直到 8 年前
        1
  •  4
  •   June7    8 年前

    有一种更简单的方法来导入csv!您可以使用Microsoft文本ODBC驱动程序。

    Sub Import()
       Dim conn as new ADODB.Connection
       Dim rs as new ADODB.Recordset
       Dim f as ADODB.field
    
       conn.Open "DRIVER={Microsoft Text Driver (*.txt; *.csv)};DBQ=c:\temp;"
       rs.Open "SELECT * FROM [test.txt]", conn, adOpenStatic, adLockReadOnly, adCmdText
    
       While Not rs.EOF
          For Each f In rs.Fields
             Debug.Print f.name & "=" & f.Value
          Next
       Wend
    End Sub
    

    您可以从“选择”更改为“插入”,然后与“选择”组合在一起。

    您可以在注册表项中进行一些设置。 \\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Text :

    格式:制表符分隔、csvdelimited、分隔(x),其中x=一些字符

    第一行具有名称:0,1

    字符集:OEM、ANSI

        2
  •  10
  •   HansUp    16 年前

    在许多情况下,导入csv的最简单方法是使用transfertext方法。

    有关详细信息,请参阅此msdn链接: TransferText Method [Access 2003 VBA Language Reference]

    下面是一个示例transfertext命令,用于将c:\somefolder\datafile.csv导入名为tblimport的表中。最后一个参数hasFieldNames为false,表示csv文件不包含字段名。

    DoCmd.TransferText acImportDelim, "YourCustomSpecificationName", _
        "tblImport", "C:\SomeFolder\DataFile.csv", False
    

    这个 规格名称 参数是可选的。但是,通过创建自己的导入规范并将其名称包含在transfertext命令中,通常可以获得更好的结果。该规范允许您标识要将数据加载到哪个表字段、调整数据类型以及一整套其他选项。您可以在手动导入数据文件时创建自己的导入规范…选择自定义导入选项,并将这些选项保存为命名规范。(在导入向导对话框中查找“高级”按钮。)

        3
  •  9
  •   Valid    10 年前

    我找到了一种将整个CSV导入到Access中的好方法。 我的任务是将三个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 dbs,这是不可接受的。

    我最终做的是创建自己的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)、所需的table name和pagenum(表引用)。(我用这个来区分桌子。在XML字符串中,我有一个基于pagenum的if语句,其中if pagenum是1;将这些列添加到字符串中)。

    只要csv文件不在名称[扩展名之外]中包含“.”(句点),这对于您导入csv文件的所有需求都非常有用。为此,在导入文件之前,需要使用脚本文件系统对象来获取文件,并更改其名称以使用下划线而不是句点之类的内容。

    我知道这可能有点冗长,但在这方面,很少有可靠和有用的资源。我花了将近一天的时间来削减选择,并解决了VBA的混乱。我希望这能帮助那些和我一样有麻烦的人。

        4
  •  3
  •   Aaron Kempf    15 年前

    大容量插入通常更快,它将在x64机器上工作。上面提到的文本驱动程序可能无法在某些X64环境中工作。

    我建议不要使用格式化文件,没有它就简单多了。

    http://msdn.microsoft.com/en-us/library/ms188365.aspx

    批量插入AdventureWorks2008r2.Sales.SalesOrderDetail 来自“f:\orders\lineitem.tbl” 用 ( fieldTerminator='', rowTerminator='\n' )

    推荐文章