Leggere Files e cartelle con la funzione "Dir"

 

Sicuramente, anche se non rientra nella quotidianità del nostro lavoro su Excel, ogni tanto è utile sapere come ottenere un elenco dei files e delle cartelle che sono nei nostri dischi fissi o nei CD usando il suo VBA.

Vorrei mostrare un metodo che ci permettere di compiere questa operazione.

 

Preparazione del lavoro

Intanto inizio col disegnare sul foglio una ComboBox ed alcuni pulsanti prelevati dalla barra Strumenti di controllo.

 

  A B C D E
1                    
2          
3          

Fatto questo lavoro sul foglio di lavoro possiamo recerci nel VBA (ALT +F11 oppure Dal menù Strumenti ---> Macro ---> Visual Basic Editor, ecc).

Il lavoro per popolare ed usare la ComboBox1 del foglio:

Facciamo iniziare il lavoro entrando nel modulo relativo a ThisWorkbook

In questo modulo provvediamo a scrivere la piccola routine che provvederà a riempire la ComboBox del Foglio:

Private Sub Workbook_Open()
Dim Fs, d, dc 'inizializiamo le variabili
Set Fs = CreateObject("Scripting.FileSystemObject") ' usiamo il riferimento al FileSystemObject
Set dc = Fs.Drives ' con dc vengono rilevate tutte le Unità disco del PC
For Each d In dc ' per ogni d (unità) nell'insieme dc (drives)
Sheets("Foglio3").ComboBox1.AddItem d.DriveLetter ' per riferirci ad un oggetto (ComboBox1) che si trova nel foglio3
Next
Set Fs = Nothing ' poi si cancellano le tre variabili per liberare la memoria
Set d = Nothing
Set dc = Nothing
End Sub

In questa routine, facendo riferimento al FileSystemObject, abbiamo accesso, tra le altre cose, all'insieme Drives che contiene tutte le unità disco presenti nel nostro computer e che andremo di seguito a leggere col ciclo For Each ... Next mettendole nella ComboBox.

 

Scrittura del Codice

La cosa dovrebbe funzionare in questo modo.

Scelta una unità disco dalla ComboBox ci viene mostrato un elenco che mostra nella prima parte un elenco di cartelle e, subito dopo, l'elenco continua con altri files presenti nella radice della unità scelta.

Selezioniamo una delle cartelle elencate possiamo visualizzarne il relativo contenuto nella colonna susseguente.

Così fino a quando non decidiamo di porre termine all'operazione.

Una discriminante per sapere se abbiamo selezionato una cella che contiene il nome della cartella da andare ad esaminare è quella di leggerne il colore.

Infatti nel codice che andremo a vedere le celle che conterranno i nomi delle cartelle del disco fisso verranno colorate.

 

Nella scrittura del codice procedo in questo modo:

  1. il codice per la ComboBox per scegliere l'unità disco che voglio analizzare
  2. il codice per ciascuno dei pulsanti per eseguire l'esplorazione della unità disco scelta
  3. il codice per due funzioni che hanno il compito di restituire le cartelle ed i files e per risparmiare codice da scrivere per i vari elementi

Le due funzioni potrebbere essere inglobate nel codice dei quattro oggetti, ma siccome verrebbe su del codice ripetitivo preferisco mettere queste istruzioni in funzioni esterne da richiamare quando necessario.

Anticipo che le due funzioni assolvono al compito di leggere le cartelle ed i files del disco rigido.

Scrittura del codice per la ComboBox.

Alla ComboBox è assegnato il compito di elencare tutte le cartelle ed i files del disco ivi selezionato.

Nel modulo relativo al foglio dove è stata disegnata (nell'esempio il Foglio3) è necessario scrivere del codice che viene eseguito quando, dalla ConboBox, scegliamo una unità disco.

Con questa routine prima leggiamo le cartelle dell'unità scelta, poi i files eventualmente presenti.

Da notare è l'istruzione conclusiva:

ActiveCell.Activate

che toglie il focus dal comando usato e lo riporta alla cella rpecedentemente selezionata. Questa cosa non funziona con ActiveCell.Select.

Private Sub ComboBox1_Change()
If ComboBox1.ListIndex = -1 Then Exit Sub
Dim Ricerca As String, Attrib As Long
Dim C As Integer, R As Integer
With Range("A3").CurrentRegion.Interior ' vengono cancellati eventuali colori precedentemente assegnati alle celle interessate
.ColorIndex = xlNone
End With
Range("A3").CurrentRegion.ClearContents ' viene cancellaro tutto il contenuto precedentemente scritto
Range("A3") = ComboBox1.Text & ":\" ' viene subito scritto quel che è stato scelto
ComboBox1.ListIndex = -1
Ricerca = Range("A3")
C = 1: R = 4
Call MostraCartelle(Ricerca, C, R) ' si viene dirottati nella routine per la ricerca delle cartelle
Attrib = vbArchive + vbReadOnly + vbHidden + vbSystem + vbNormal
While Cells(R, C) <> "" ' si va alla ricerca della prima cella disponibile (vuota)
R = R + 1
Wend
Call MostraFiles(Ricerca, Attrib, C, R) ' quindi in quella per la ricerca dei files
ActiveCell.Activate
End Sub

Scrittura del codice per il pulsante "Solo Cartelle".

Come intuibile, premendo questo pulsante dovremmo avere un elenco di tutte le cartelle relative alla cartella selezionata dall'elenco.

Dpo aver letto il contenuto della cella selezionata ed aver cancellato la porzione di foglio da eventuali dati precedentemente scritti (Range("A3").CurrentRegion.CurrentRegion.Offset(0, C).ClearContents) andiamo a cercare le cartelle eventualmente contenute nella cartella scelta

Private Sub CommandButton1_Click()
' solo cartelle
Dim Ricerca As String
Dim C As Integer, R As Integer
If ActiveCell.Interior.ColorIndex = xlNone Then Exit Sub
C = ActiveCell.Column
With Range("A3").CurrentRegion.Offset(0, C).Interior
.ColorIndex = xlNone
End With
Range("A3").CurrentRegion.CurrentRegion.Offset(0, C).ClearContents
Ricerca = Cells(3, C) & ActiveCell & "\"
R = 4: C = C + 1
Cells(3, C) = Ricerca
Call MostraCartelle(Ricerca, C, R)
ActiveCell.Activate
End Sub

Scrittura del codice per il pulsante "Solo Files".

Stessa procedura di quella appena vista, solo che ora andremo a cercare i files della cartella scelta dall'elenco. Tuttavia ora mandiamo alla routine MostraFiles anche l'argomento Attrib che ha come valori vbArchive + vbReadOnly + vbHidden + vbSystem + vbNormal

Private Sub CommandButton2_Click()
' solo files
Dim Ricerca As String, Attrib As Long
Dim C As Integer, R As Integer
If ActiveCell.Interior.ColorIndex = xlNone Then Exit Sub
C = ActiveCell.Column
With Range("A3").CurrentRegion.Offset(0, C).Interior
.ColorIndex = xlNone
End With
Range("A3").CurrentRegion.CurrentRegion.Offset(0, C).ClearContents
Ricerca = Cells(3, C) & ActiveCell & "\"
R = 4: C = C + 1
Cells(3, C) = Ricerca
Attrib = vbArchive + vbReadOnly + vbHidden + vbSystem + vbNormal
Call MostraFiles(Ricerca, Attrib, C, R)
ActiveCell.Activate
End Sub

Scrittura del codice per il pulsante "Files e Cartelle".

Viste queste due routine legate ai pulsanti "Solo Cartelle" e "Soli Files" possiamo procedere velocemente alla routine legata al terzo pulsante: "Cartelle e Files".

Private Sub CommandButton3_Click()
' files e cartelle
Dim Ricerca As String, Attrib As Long
Dim C As Integer, R As Integer
If ActiveCell.Interior.ColorIndex = xlNone Then Exit Sub
C = ActiveCell.Column
With Range("A3").CurrentRegion.Offset(0, C).Interior
.ColorIndex = xlNone
End With
Range("A3").CurrentRegion.CurrentRegion.Offset(0, C).ClearContents
Ricerca = Cells(3, C) & ActiveCell & "\"
R = 4: C = C + 1
Cells(3, C) = Ricerca
Call MostraCartelle(Ricerca, C, R)
Attrib = vbArchive + vbReadOnly + vbHidden + vbSystem + vbNormal
Call MostraFiles(Ricerca, Attrib, C, R)
ActiveCell.Activate
End Sub

Le due Funzioni, o meglio, procedure con argomenti.

E' giunto finalmente il momento di fare la conoscenza delle due Procedure con argomento che ho preparato separatamente per semplificare la scrittura del codice fin qui visto.

La prima: quella che legge le cartelle

A questa routine vengono passati questi argomenti:

Trovata la cartella la si scrive nella cella del foglio che, per essere distinta da eventuali nomi di files, viene anche colorata

Siccome stiamo cercando le sole cartelle la prima volta che usiamo la funzione Dir() specifichiamo due argomenti:

Nelle istruzioni che seguono, una volta scartati eventuali nomi rappresentati da "." o da ".." che rappresentano la directory corrente e quella di livello superiore, controlliamo che quel che abbiamo letto dal disco sia una cartella:

If (GetAttr(Cartella & MioNome) And vbDirectory) = vbDirectory Then....

Sub MostraCartelle(Cartella As String, Colonna As Integer, Riga As Integer)
Dim MioNome
On Error Resume Next
MioNome = Dir(Cartella, vbDirectory) ' si inizia col leggere il primo elemento
Do While MioNome <> "" ' Inizia il loop.
If MioNome <> "." And MioNome <> ".." Then
If (GetAttr(Cartella & MioNome) And vbDirectory) = vbDirectory Then
Cells(Riga, Colonna) = MioNome
With Cells(Riga, Colonna).Interior ' viene colorata la cella che ospita il nome della cartella
.ColorIndex = 36
.Pattern = xlSolid
End With
Riga = Riga + 1
End If
End If
MioNome = Dir() ' legge l'elemento successivo
Loop
If Err Then
MsgBox Err.Description
End If
End Sub

La seconda: quella che legge i files

A questa routine vengono passati i seguenti argomenti:

La routine è più semplice di quella appena vista.

Infatti passandole come argomento gli attributi vbArchive + vbReadOnly + vbHidden + vbSystem + vbNormal dai quali viene escluso il vbDirectory, vengono automaticamente escluse dalla lettura le cartelle e quindi sono da escludere controlli più approfonditi.

Sub MostraFiles(Cartella As String, Attributo As Long, Colonna As Integer, Riga As Integer)
Dim MioNome
On Error Resume Next
MioNome = Dir(Cartella, Attributo)
Do While MioNome <> ""
Cells(Riga, Colonna) = MioNome
Riga = Riga + 1
MioNome = Dir()
Loop
If Err Then
MsgBox Err.Description
End If
End Sub

Questo studio, potrebbe essere uno spunto per eseguire altri tipi di applicativi, come per esempio preparare una base per la stampa di copertine, oppure per avere un elenco di tutti i contenuti dei nostri CD.

 

Ma vediamo un altro esempio d'uso della funzione Dir().

Cercare un elenco di un determinato tipo di file come potrebbe essere la ricerca di tutti i files immagini, o .xls, o .doc o altro.

La routine è legata ad un pulsante preso dalla barra Strumenti di controllo posto in uno dei fogli della cartella di Excel.

Per questo lavoro è richiesto che nello stesso foglio dove abbiamo disegnato il pulsante:

Private Sub CommandButton1_Click()
' vengono effettuati dei controlli preliminari per verificare se nelle celle D1 e E1
' sono stati immessi l'estensione del file da cercare e la cartella dove cercare

If Range("D1") = "" Then
MsgBox "Occorre scrivere il tipo di file da cercare"
Range("D1").Select
Exit Sub
End If
If Range("E1") = "" Then
MsgBox "Specificare la cartella dove cercare"
Range("E1").Select
Exit Sub
End If

Dim Ext, Percorso, NomeFile
Dim Riga, Colonna
Columns("A:A").ClearContents
' si inizia il lavoro aggiustando
' sia la estensione del file aggiungendo un *. prima della estensione (es:*.xls)
' sia il nome della cartella agiungendo un \ finale (es: F:\documenti\filesXLS\)

Ext = Range("D1")
If Left(Ext, 1) <> "*" Then
Ext = "*." & Ext
End If
Percorso = Range("E1")
If Right(Percorso, 1) <> "\" Then
Percorso = Percorso & "\"
End If
' si inizia il lavoro leggendo il contenuto del disco accettando solo i files che hanno l'estensione indicata
Riga = 3: Colonna = 1
NomeFile = Dir(Percorso & Ext)
Do While NomeFile <> ""
Cells(Riga, Colonna) = NomeFile
Riga = Riga + 1
NomeFile = Dir()
Loop
End Sub

Con questo penso di aver esaurito l'argomento che riguarda gli usi più comuni chce si possono fare con la funzione Dir().