Loading a text file into an array

Loading a text file into an array

  1. Add a global property (in the window):
TextArray() As String
  1. Add a File Type Set (TEXT)

  2. Put the code below in a PushButton or in a [quote]Method[/quote] and call it from a a Menu / PushButton, whatever object you like.

[code]Sub Action()
// ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
//
// Load a user selected TEXT file into an array
//
// Created after advice from Beatrix, confirmed by Marco in the Forum
//
// 2016-05-24
//
// ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
//
Dim Import_TXTFI As FolderItem
Dim Import_TXTTIS As TextInputStream
Dim Field_Cnt As Integer
Dim One_Line As String

// Aak the user to choose a text file
Import_TXTFI = GetOpenFolderItem(FT.TXT)
If Import_TXTFI <> Nil Then
If Import_TXTFI.Exists Then
Try
// Get a TextInputStream Reference
Import_TXTTIS = TextInputStream.Open(Import_TXTFI)

    // Set the default encodings to UTF-8 (Useless)
    Import_TXTTIS.Encoding = Encodings.UTF8
    
    // Load one line
    One_Line = Import_TXTTIS.ReadLine

    // Compute the number of tabs
    Field_Cnt = CountFields(One_Line,Chr(9))
    
    // Assign the data to the Array
    TextArray.Append One_Line
    
    // Load the data and place it into the TextArray (array), one line at a time…
    While Not Import_TXTTIS.EOF
      // Load one line at a time and set it into an array
      One_Line = Import_TXTTIS.ReadLine
      
      // Assign the loaded line into the array
      TextArray.Append One_Line
      
      // To avoid 1, Infinite Loop
      If UserCancelled Then Exit
    Wend
    
    // 
    // Here, TextArray holds the contents of the selected text file.
    // After my report (yesterday), I get an eye on the array contents and it is a single dimension array,
    // Each entry TextArray(i) holds: TextField1 \\Tab TextField2 \\Tab TextField3 \\Tab TextField4 // etc.
    // 
    
    // In case of IOException
  Catch e As IOException
    Import_TXTTIS.Close
    MsgBox("Error accessing file " + Import_TXTFI.DisplayName + ".")
  End Try
End If

End If
End Sub
[/code]

Is there a question here?
What are you trying to do?

This code loads the contents of a text file into an array of strings, with a single dimension.
Although it counts the fields, it never splits them into fields.

Are you trying to get a multi-dimension array?
If so, you may struggle because you don’t know in advance how many fields each row contains.
Thats a good reason to leave it as a single dimension array, and only SPLIT() at the point you need the fields later.

Although there is a .close in the exception handler, the file is not explicitly closed at the end of the sub

you should have a .close after the Wend

While Not Import_TXTTIS.EOF // code Wend Import_TXTTIS.Close

Hi Jeff,

Thank you for your answer (full of questions, and you are right).

Doh ! I really was not fine yesterday (walking bside my shoes !). Yes, you are right.

Fields:
Once more, you are right.

Yes, I was thinking I was doing so, but I discovers lately that this was not the case as you wrote.

Here’s the why:
I was told yesterday that the Listbox Class is a displayer (not a container like TextField/TextAres). And the next part of the advice was to use either a dictionary or an array.

Nota: I think I do not used Arrays since… AppleSoft BASIC, nearly 30 years ago). [not sure]

The thing I do not understand (as seen as reading my own message / code) is… how to fill a multi-dimension array ?

BTW: your advice is to leave the array as one dimension ?

Basic (sic) things,w hen unused, tends to be forgotten.

The target idea is to make changes in the array (merge, etc.) and then populate a Listbox with the results as adviced.

Yes
You can compare A/B/C with A/B/C more easily if they are both strings (even if they hold tabs) ,
than if you split both and then try to compare A <> A B<>B C<>C etc

As you read, you can count the fields.
Maintain a ‘maximum number of fields’ variable … if countfields > maxfields then maxfields = countfields

When you have the whole file, if you want to display the data, you can add the rows to a listbox that has been created with (maxfields) columns.

Thanks.

this bit of code can be made MUCH faster

  // Load the data and place it into the TextArray (array), one line at a time…
        While Not Import_TXTTIS.EOF
          // Load one line at a time and set it into an array
          One_Line = Import_TXTTIS.ReadLine
          
          // Assign the loaded line into the array
          TextArray.Append One_Line
          
          // To avoid 1, Infinite Loop
          If UserCancelled Then Exit
        Wend
dim s as string=Import_TXTTIS.READALL
TextArray = Split(s,endofline)

THANK YOU DAVE !

I remember why I used that code: I can modify the line contents (csv file loading for example).

BUT: your advice is welcome for all other cases (real TXT file for example).

Thanks again pal.