Caricare un file di testo da elaborare

Stato
Chiusa ad ulteriori risposte.

giulianovac

Access/VBA Expert
Staff
9 Giugno 2018
5.260
245
Italy
2019
415
A volte capita di dover accedere ad un file di testo, sia esso TXT, CSV, LOG, ecc... e per leggerne i dati, riga per riga, si usa generalmente Line Input.
Durante tutta l'elaborazione, però, il file resta aperto e la velocità di esecuzione può essere rallentata perché la Line Input accede continuamente al disco il che richiede il suo tempo (dipende anche dalla velocità del disco, la dimensione del file, ecc...).

La funzione seguente, invece, carica tutto il file in memoria, o per meglio dire, in una variabile stringa, grazie alla funzione LOF() e tale contenuto potrà poi essere elaborato quandp e come meglio necessita.
Chiaro che eseguire elaborazioni in memoria è assolutamente molto più veloce che non continuare ad accedere al disco, considerando anche che i dati (essendo appunto in memoria) possono essere esaminati all'infinito, mentre con Line Input, una volta acquisita la riga fine della storia.

In sostanza la sequenza di operazioni è davvero semplice:
1. apro il file
2. ne acquisisco il contenuto
3. chiudo il file

Come vedremo più avanti posso caricare un array con tutte le righe, ecco la funzione

Visual Basic:
Function ReadTextFile(FileName As String) As String
    Dim fnum As Integer, isOpen As Boolean
    On Error GoTo Error_Handler

    ' Mi faccio dare il primo numero di file libero
    fnum = FreeFile()

    ' Apro il file in lettura
    ' N.B. Utilizzo la modialità Binary perché a volte i file potrebbero contenere caratteri strani
    ' che bloccherebbero la lettura del contenuto, rendendolo incompleto   
     Open FileName For Binary As #fnum

    ' Se sono arrivato qui, significa che il file è stato aperto con successo, senza errori
    isOpen = True

    ' Acquisisco l'intero contenuto del file in una sola operazione
    ReadTextFile = Input(LOF(fnum), fnum)

Error_Handler:
    ' chiudo il file, sia che si sia verificato un errore o meno.
    If isOpen Then Close #fnum
  
End Function
A questo punto possiamo chiamare la funzione sopra così:
Visual Basic:
Dim sContents As String
sContents = ReadTexFile(percorso_file)
Ora che abbiamo caricato il file in una variabile sContents, possiamo elaborare riga per riga utilizzando un array, servendoci della funzione Split che separa una stringa in base ad un determinato separatore.
In questo esempio, come separatore, uso la costante vbCrLf perché voglio separare tutte le righe e vbCrLf è di norma la più utilizzata per questo scopo.
Però certi file di testo MS-DOS potrebbero usare solo la vbLf, basta provare per capire quale sia quella utilizzata nel file.

Codice:
Dim ar() As String
ar = Split(sContents, vbCrLf)
Abbiamo così ottenuto un array di <n> elementi in cui ogni elemento contiene la riga del file.
Il numero di elementi può essere dedotto utilizzando la funzione UBound(array) la U sta per Upper (vi è anche la sorella LBound in cui L sta per Lower).

Possiamo elaborare ogni riga utilizzando un ciclo:
Codice:
Dim i As Long
For i = 0 To Ubound(ar)
    Debug.Print ar(i)
Next i
Come dicevo più sopra, in tal modo sarà possibile rielaborare il contenuto all'infinito in quanto l'indice (i) ci permetterà di accedere a qualsiasi elemento dell'array.
 

giulianovac

Access/VBA Expert
Staff
9 Giugno 2018
5.260
245
Italy
2019
415
ges @ges
grazie per la correzione.
cappello_saluta
 

Marius44

VBA Expert
Moderatore
9 Settembre 2015
7.957
145
77
Catania
Excel2010
413
La "classe" non è acqua (anche se non stiamo giocando a calcio)
Davvero complimenti.

Ciao,
Mario
 

giulianovac

Access/VBA Expert
Staff
9 Giugno 2018
5.260
245
Italy
2019
415
Dimenticavo di dire che il ciclo For/Next indicato può essere utile nel caso di debbano eseguire elaborazioni sul contenuto dell'array.

Ma se occorre semplicemente 'copiare' i dati in un foglio Excel allora si può utilizzare la funzione Transpose:
Codice:
Range("A1").Resize(UBound(ar)+1)=Application.Transpose(ar)
Suggerisco la lettura di questo articolo:
 
  • Like
Reactions: Rubik72
Stato
Chiusa ad ulteriori risposte.

Sostieni ForumExcel

Aiutaci a sostenere le spese e a mantenere online la community attraverso una libera donazione!