Search code examples
vbacsvexcelexcel-2007export-to-excel

Open CSV file with correct data format for each column using TextFileColumnDataTypes?


I am using the VBA-code below to open a csv-file in Excel (the code simulates the Data\Text to Columns - command). In the code it's necessary to specify an array for the property TextFileColumnDataTypes , which for every column in the csv-file specifies a data format (2 = text format).

However, since I don't know how many columns the csv-file will have, I would like to specify the format 2 (= text format) for ALL columns in the csv-file. The problem right now is that I can only specify the data format for a fixed number of columns (in the example below it's 3 columns).

Any help to solve that problem is highly appreciated :)

===============================================

Here is the full code I am using:


    With ThisWorkbook.Worksheets(1).QueryTables.Add(Connection:= _
        "TEXT;C:\test.csv", Destination _
        :=ThisWorkbook.Worksheets(1).Range("$A$1"))
        .name = "Query Table from Csv"
        .FieldNames = True
        .RowNumbers = False
        .FillAdjacentFormulas = False
        .PreserveFormatting = True
        .RefreshOnFileOpen = False
        .RefreshStyle = xlInsertDeleteCells
        .SavePassword = False
        .SaveData = True
        .AdjustColumnWidth = True
        .RefreshPeriod = 0
        .TextFilePromptOnRefresh = False
        .TextFilePlatform = 850
        .TextFileStartRow = 1
        .TextFileParseType = xlDelimited
        .TextFileTextQualifier = xlTextQualifierDoubleQuote
        .TextFileConsecutiveDelimiter = False
        .TextFileTabDelimiter = False
        .TextFileSemicolonDelimiter = False
        .TextFileCommaDelimiter = True
        .TextFileSpaceDelimiter = False
        .TextFileColumnDataTypes = Array(2, 2, 2)
        .TextFileDecimalSeparator = "."
        .TextFileThousandsSeparator = ","
        .TextFileTrailingMinusNumbers = True
        .Refresh BackgroundQuery:=False
        .Delete     
    End With

Solution

  • Here is one way to find the number of columns from a closed CSV without opening it in Excel.

    I am assuming the following.

    1) You are opening a Comma Separated File. If not then you will have to amend the code appropriately

    2) Row 1 in the CSV has Headers (At least 1 header in any of the Column)

    Try this (I tested it but if you get any error let us know :)

    Option Explicit
    
    Const ExlCsv As String = "C:\test.csv"
    
    Sub Sample()
        Dim MyData As String, strData() As String, TempAr() As String
        Dim ArCol() As Long, i As Long
    
        '~~> Open the text file in one go
        Open ExlCsv For Binary As #1
        MyData = Space$(LOF(1))
        Get #1, , MyData
        Close #1
        strData() = Split(MyData, vbCrLf)
    
        '~~> Check for any empty headers and replace ",," by ","
        Do While InStr(1, strData(0), ",,") > 0
            strData(0) = Replace(strData(0), ",,", ",")
        Loop
    
        '~~> Split the headers to find the number of columns
        TempAr() = Split(strData(0), ",")
    
        '~~> Create our Array for TEXT       
        ReDim ArCol(1 To UBound(TempAr))
        For i = 1 To UBound(TempAr)
            ArCol(i) = 2
        Next i
    
        With ActiveSheet.QueryTables.Add(Connection:= _
            "TEXT;" & ExlCsv, Destination:=Range("$A$1") _
            )
            .Name = "Output"
            .FieldNames = True
            .RowNumbers = False
            .FillAdjacentFormulas = False
            .PreserveFormatting = True
            .RefreshOnFileOpen = False
            .RefreshStyle = xlInsertDeleteCells
            .SavePassword = False
            .SaveData = True
            .AdjustColumnWidth = True
            .RefreshPeriod = 0
            .TextFilePromptOnRefresh = False
            .TextFilePlatform = 1252
            .TextFileStartRow = 1
            .TextFileParseType = xlDelimited
            .TextFileTextQualifier = xlTextQualifierDoubleQuote
            .TextFileConsecutiveDelimiter = False
            .TextFileTabDelimiter = True
            .TextFileSemicolonDelimiter = False
            .TextFileCommaDelimiter = True
            .TextFileSpaceDelimiter = False
            .TextFileColumnDataTypes = ArCol
            .TextFileTrailingMinusNumbers = True
            .Refresh BackgroundQuery:=False
        End With
    End Sub
    

    EDIT

    Alternatively, here is a much simpler method (Wondering why didn't I think of it before...)

    Option Explicit
    
    Const ExlCsv As String = "C:\test.csv"
    
    Sub Sample()
        ActiveSheet.Cells.NumberFormat = "@"
    
        With ActiveSheet.QueryTables.Add(Connection:= _
            "TEXT;" & ExlCsv, Destination:=Range("$A$1") _
            )
            .Name = "Output"
            .FieldNames = True
            .RowNumbers = False
            .FillAdjacentFormulas = False
            .PreserveFormatting = True
            .RefreshOnFileOpen = False
            .RefreshStyle = xlInsertDeleteCells
            .SavePassword = False
            .SaveData = True
            .AdjustColumnWidth = True
            .RefreshPeriod = 0
            .TextFilePromptOnRefresh = False
            .TextFilePlatform = 1252
            .TextFileStartRow = 1
            .TextFileParseType = xlDelimited
            .TextFileTextQualifier = xlTextQualifierDoubleQuote
            .TextFileConsecutiveDelimiter = False
            .TextFileTabDelimiter = True
            .TextFileSemicolonDelimiter = False
            .TextFileCommaDelimiter = True
            .TextFileSpaceDelimiter = False
    
             '<~~ This doesn't make any difference anymore
            .TextFileColumnDataTypes = Array(2)
    
            .TextFileTrailingMinusNumbers = True
            .Refresh BackgroundQuery:=False
        End With
    End Sub