schema.ini file not working for MS Access

前端 未结 3 1515
故里飘歌
故里飘歌 2021-01-29 01:38

I have a bunch of csv files that I import via VBA into tables in Access. I also have a schema.ini file in the same directory as the csv files that I am importing. Despite fields

相关标签:
3条回答
  • 2021-01-29 01:45

    There are essentially two ways to pre-set the data columns for text file (.txt, .csv, .tab) imports into an Access database, both of which use different VBA methods.

    1. Specifications object (saved within the database)

    Here, you use DoCmd.TransferText where one of the arguments is an optional specification name (no extension or path).

    DoCmd.TransferText(TransferType, SpecificationName, TableName, FileName, 
                        HasFieldNames, HTMLTableName, CodePage)
    

    To create this specification object, you need to manually import an example text file just once, walk through the wizard and just before last section to finish, click the Advanced button which summarizes all items you just specified --field names, lengths, data types, etc. Go ahead and save that entire summary file by clicking Save As on the dialog window and remember the name you give it which is the specification argument in the above.

    In fact, once specs is saved, you can cancel the wizard altogether. Import/Export specs are stored in the queryable Access system table, MSysIMEXSpecs, and can be used and reused even overwritten (via wizard again) for the life of the .accdb file. In fact, you can even import into other databases (clicking advanced in External Data wizard).

    2. Schema.ini file (saved outside the database)

    Here, the text file behaves as an external table since it contains schema which can be linked to Access or opened via a recordset as outlined on Microsoft.com. Now a workaround is needed since this external file does not automate with an import method. Below is a modification of the linked table option where a local table is created through a Make-Table query (carrying all schema and structure and data). Afterwards, the linked table is destroyed (not the table itself just the link). Adjust this into your application, possibly in a button OnClick or form OnOpen events or called from a VBA module via an AutoExec macro (when db first opens).

    Function LinkSchema() 
    Dim db As DATABASE, tbl As TableDef 
    
    Set db = CurrentDb() 
    Set tbl = db.CreateTableDef("Linked Text")
    
    tbl.Connect = "Text;DATABASE=c:\my documents;TABLE=csvFile_linked" 
    tbl.SourceTableName = "csvFile.csv" 
    
    db.TableDefs.Append tbl 
    db.TableDefs.Refresh 
    
    db.Execute "SELECT * INTO csvFile_local FROM csvFile_linked", dbFailOnError
    db.TableDefs.Delete("csvFile_linked")
    
    Set tbl = Nothing
    Set db = Nothing
    
    End Function
    

    As described above, I personally never use the schema.ini file which might even be an outmoded legacy approach as Microsoft support is not up to date. Specs provide a fluid flexibility in that they work integrally with import/export procedures. Plus, they are saved directly in database without needing to manage them externally.

    0 讨论(0)
  • 2021-01-29 01:54

    I have a half answer. I found no way to avoid the Col# option in the schema.ini file despite what it says here: https://msdn.microsoft.com/en-us/library/ms709353(v=VS.85).aspx (If you know how to do it, post an answer and I'll give you credit.)

    Other than that I figured out how to force a data type on a field that has a bunch of null values at the top of the file.

    (Note that the link above says you can use ColNameHeader=True MaxScanRows=0 and it will look at the entire file for a format. That didn't work for me.)

    Here is my working sample (my answer)....

    Create this csv file and save it directly on your C drive (no folder) and save it as test.csv:

    +-----------+----------+---------+
    | FirstName | LastName | Anumber |
    +-----------+----------+---------+
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  |         |
    | Robert    | King     |         |
    | Nancy     | Davolio  | 1.1     |
    | Robert    | King     | 2.1     |
    +-----------+----------+---------+
    

    The large number of Null values in the Anumber field is important to this.

    In the SAME LOCATION create a text file and save it has schema.ini with the following in it:

    [test.csv]
    ColNameHeader=True
    MaxScanRows=0
    CharacterSet=ANSI
    Format=CSVDelimited
    Col1="First Name" Char
    Col2="Last Name" Char
    Col3="Anumber" Double 
    

    Then run this code in MS Access VBA (2013 for me):

    Sub ImportSchemaTable()
        Dim db As DAO.Database
        Set db = CurrentDb()
        db.Execute _
        "SELECT * INTO test FROM [Text;FMT=CSVDelimited;HDR=Yes;DATABASE=C:\;].[test#csv];", dbFailOnError
        db.TableDefs.Refresh
        RefreshDatabaseWindow
    End Sub
    

    And a table called "test" will be created using the test.csv file and the schema.ini file (in the same location as the test.csv file) and the "Anumber" field will be formatted as a "Number" despite all of the Null values at the top of the field. If you do not use the schema.ini file, the "Anumber" field will be formatted as a Short Text type.

    Edit: Change "C:\" in the Sub above to where ever you want to have your csv file AND schema.ini file.

    0 讨论(0)
  • 2021-01-29 01:59

    I think your syntax for field specifications is wrong.
    From http://www.htmlgoodies.com/primers/database/work-with-text-file-data-using-the-microsoft-text-driver-creating-a-csv-data-file.html

    Understanding the Schema.ini file line by line

    Line 5 and above: Specify each column’s Name, Data type, Width if applicable. The general syntax is

    Col(n)=<column name> <data type> <Width width>

    Where n is the position of the column in the CSV file, and Width is mandatory only for Text.

    and https://msdn.microsoft.com/en-us/library/ms709353%28VS.85%29.aspx

    The next entry designates fields in a table by using the column number (Coln) option, which is optional for character-delimited files and required for fixed-length files.

    So you can omit Col1=, Col2=, etc. as you did, but the = belongs between Col(n) and the column name, not between name and type. So replace the = by space.

    In addition, INTEGER may not be a valid data type to import into Access - use Short or Long instead. But I'm not sure about that.

    Edit: I haven't actually used this (or if I have, I forgot about it), but from the references I linked it should look:

    [ForClsDatedModel_2015 0702_1004-1254.csv]
    ColNameHeader=True
    Format=CSVDelimited
    "Ticker" TEXT
    "WT Def BSS MF-WT" LONG
    "Cyc BSS MF-WT" DOUBLE
    

    or if that doesn't work, try including Coln - most examples include them, even if it's CSVDelimited:

    [ForClsDatedModel_2015 0702_1004-1254.csv]
    ColNameHeader=True
    Format=CSVDelimited
    Col1="Ticker" TEXT
    Col2="WT Def BSS MF-WT" LONG
    Col3="Cyc BSS MF-WT" DOUBLE
    
    0 讨论(0)
提交回复
热议问题