vbaformatted-input

loading formatted data in VBA from a text file


I'm looking for the best way of loading formatted data in VBA. I’ve spent quite some time trying to find the equivalent of C-like or Fortran-like fscanf type functions, but without success.

Basically I want to read from a text file millions of numbers placed on many (100,000’s) lines with 10 numbers each (except the last line, possibly 1-10 numbers). The numbers are separated by spaces, but I don’t know in advance the width of each field (and this width changes between data blocks). e.g.

  397143.1   396743.1   396343.1   395943.1   395543.1   395143.1   394743.1   394343.1   393943.1   393543.1

   -0.11    -0.10    -0.10    -0.10    -0.10    -0.09    -0.09    -0.09    -0.09    -0.09

 0.171  0.165  0.164  0.162  0.158  0.154  0.151  0.145  0.157  0.209 

Previously I’ve used the Mid function but in this case I can’t, because I don’t know in advance the width of each field. Also it's too many lines to load in an Excel sheet. I can think of a brute force way in which I look at each successive character and determine whether it’s a space or a number, but it seems terribly clumsy.

I’m also interested in pointers on how to write formatted data, but this seems easier -- just format each string and concatenate them using &.


Solution

  • The following snippet will read whitespace-delimited numbers from a text file:

    Dim someNumber As Double
    
    Open "YourDataFile.txt" For Input As #1
    
    Do While Not (EOF(1))
        Input #1, someNumber
        `// do something with someNumber here...`
    Loop
    
    Close #1
    

    update: Here is how you could read one line at a time, with a variable number of items on each line:

    Dim someNumber As Double
    Dim startPosition As Long
    Dim endPosition As Long
    Dim temp As String
    
    Open "YourDataFile" For Input As #1
    
    Do While Not (EOF(1))
        startPosition = Seek(1)  '// capture the current file position'
        Line Input #1, temp      '// read an entire line'
        endPosition = Seek(1)    '// determine the end-of-line file position'
        Seek 1, startPosition    '// jump back to the beginning of the line'
    
        '// read numbers from the file until the end of the current line'
        Do While Not (EOF(1)) And (Seek(1) < endPosition)
            Input #1, someNumber
            '// do something with someNumber here...'
        Loop
    
    Loop
    
    Close #1