Import .csv file to MSAccess table without losing leading zeros

时间:2016-08-31 17:34:05

标签: csv ms-access import access-vba leading-zero

My objective is to automate the import of a .csv file into an Access table, retaining all data in the csv file, specifically leading zeros.

The csv file will have a varying number of columns every time, so the table it needs to be imported into will have to be created on the fly. Also, the decision was made to have every column defined as text(255).

Here's the relevant code for that process, leaving out the part where the user navigates to a folder and selects a .csv file.

Notes on variables:

FilePathAndName contains the full path and file name of the .csv file

TableName contains the name of the MSAccess table I am creating

HeaderRow contains the first row of the csv file which has column names. The column names will never contain a comma.

ColumnNames() is an array to hold the column names themselves.

SQLStatement will hold a SQL DDL statement to create the table

Open FilePathAndName For Input As #1

' read first row to get column names because that will change every time
Line Input #1, HeaderRow
Close #1
ColumnNames = Split(HeaderRow, ",")

' create MSAccess table via DDL commands
TableName = "GROUPS_TEST"
SQLStatement = "CREATE TABLE " & TableName & "("
For i = 0 To UBound(ColumnNames)
    SQLStatement = SQLStatement & "[" & ColumnNames(i) & "] text(255)"
    If i < UBound(ColumnNames) Then
        SQLStatement = SQLStatement & ", "
    End If
Next i
SQLStatement = SQLStatement & ")"
DoCmd.RunSQL SQLStatement

' load .csv file into the table that was just created
DoCmd.TransferText acImportDelim, , TableName, FilePathAndName, True

It works flawlessly down to and including the DoCmd.RunSQL statement where the table is created. All columns are defined as text(255) because there are some columns which have leading zeros which must be retained. They are not numbers; they are alphanumeric values. Then the trouble begins. I execute the TransferText action and the data is imported to the table from the .csv file. Except that it strips leading zeros from the values that have them even though I specifically defined all columns as TEXT columns.

I've been googling for a couple of hours and nothing has turned up. I don't have an import/export specification because of the dynamic nature of the .csv files. And I don't know that it would make any difference anyway.

One thing that was mentioned was editing a registry setting for text files in MSAccess but I could not find specifics. I'm using Access 2007. Another idea brought up was using a schema.ini file but again due to the dynamic nature of the csv files I don't know if that would work.

Any help will be gratefully accepted. Thanks in advance.

2 个答案:

答案 0 :(得分:1)

不使用导入文件中的字段名称,而是命名导入表F1,F2,F3等中的所有字段。 将HasFieldNames参数设置为false。然后第一行将始终是文本。您可以稍后删除该行。 然后将字段名称更改为您想要的名称或将数据插入另一个表格。我总是使用这种方法,这样我就可以在将导入数据插入最终目标表之前清理它。

答案 1 :(得分:0)

这是适合我的解决方案;感谢Ryan Griffin对Stack Overflow上类似问题的回答。

重新说明要求:

1)将.csv文件导入MSAccess

2)必须在包含它们的字段中保留所有前导零

3).csv文件是动态的;列数可以(通常确实)随每次导入而变化

4)数据类型可以是所有列的文本

5)给定列的数据长度永远不会> 255

6)第一行.csv文件将始终包含列名,列名永远不会有逗号

7)列可能有也可能没有引号分隔符;如果任何列包含逗号,则该列将以引号分隔;否则它可能会也可能不会。

这是一个示例.csv文件:

名,部门,扩展

“ManyJohns,John”,02,0987

John Smallberries,“收购”,“32939”

“John Bigbootie”,0001,GIGO

系统设置:Windows 7和MSAccess 2007

我知道几年前有类似项目的注册表设置。 Win7路径是HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft \ Jet \ 4.0 \ Engines \ Text

ImportMixedTypes 的值从多数类型更改为文字

首先尝试:使用TransferText操作

变量:TableName和FilePathAndName

DoCmd.TransferText acImportDelim ,, TableName,FilePathAndName,True

请注意,没有导入规范,因为如上所述,它可以每次都更改。 结果:删除前导零并删除文本值

enter image description here

第二次尝试:将.csv文件作为Access对象打开

变量:TableName,FilePath和FileName

SQLStatement = "INSERT INTO " & TableName & " SELECT * FROM [TEXT;FMT=Delimited;HDR=YES;IMEX=1;CharacterSet=437;DATABASE=" & FilePath & "].[" & FileName & "]"
DoCmd.RunSQL SQLStatement

结果:我以前从未见过这种用法;有点酷,我想。但是,它也删除了前导零并删除了文本值。

enter image description here

第三次尝试:动态创建导入/导出规范 这是Ryan Griffin的帖子,我的解决方案是为了我的目的而改编的。谢谢你,先生;我向你致敬。

Access Data Project Importing CSV File In VBA

并且,成功。

enter image description here

由于我的.csv文件的动态特性,这里是基于Ryan工作的最终代码。 我这里没有包含变量声明;如果有兴趣让我知道,我会把一些东西放在一起更加精致。

Private Function CreateImportSpecification()

    'based on solution from Ryan Griffin 21-JUN-2012
    ImportSpecificationName = "ImportSpec_" & TableName

    xml = ""
    xml = xml & "<?xml version=""1.0"" encoding=""utf-8"" ?>" & vbCrLf
    xml = xml & "<ImportExportSpecification Path=" & Chr(34) & FilePathAndName & 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

    ' dynamically populate the 'FieldName' property of the <Column> attribute
    For i = 0 To UBound(ColumnNames)
        xml = xml & "            <Column Name=""Col" & (i + 1) & """ FieldName=""" & ColumnNames(i) & """ Indexed=""NO"" SkipColumn=""false"" DataType=""Text"" Width=""255"" />" & vbCrLf
    Next i

    xml = xml & "         </Columns>" & vbCrLf
    xml = xml & "   </ImportText>" & vbCrLf
    xml = xml & "</ImportExportSpecification>"

    ' if a specification already exists for this table, delete it
    With CurrentProject.ImportExportSpecifications
        For i = 0 To .Count - 1
            If .Item(i).Name = ImportSpecificationName Then
                .Item(i).Delete
                Exit For
            End If
        Next i
        ' add the specification to the database
        .Add ImportSpecificationName, xml
        ' could execute ImportSpecificationName right here
        ' but would need to loop through the ImportExportSpecifications again
        ' to make sure you had the right one
    End With

    DoCmd.RunSavedImportExport ImportSpecificationName

End Function

我唯一能想到的是,在导入.csv文件时,MSAccess会忽略注册表项(或者我正在修改错误的注册表项)。 最终,唯一对我有用的是动态创建导入/导出规范。 欢迎任何其他输入。