Drivelist, DirList e Filelist. -
dal 04/09/04 pagina vista:
volte
Gli "Oggetti"
ActiveX : DriveListBox, DirListBox e
FileListBox e le relative funzioni, disponibili
per progetti in VB, NON esistono in VBA. E' possibile, con un pò di
pazienza, "costruirsi" dei "surrogati" che sostituiscano questi oggetti,
ricorrendo alla funzione "CreateObject", ed usando una ComboBox e alcune
ListBox.
Esiste una
documentazione ampia nella guida in linea, che invito a leggersi, corredata
da numerosi esempi, riguardo alla funzione CreateObject, Folder, ecc. e agli argomenti
correlati. Comunque, a grandi linee, la funzione Create Object si avvale
dell'oggetto FileSystemObject per accedere al FileSystem. Infatti
CreateObject serve per creare e restituisce un riferimento a un
oggetto ActiveX. La sua sintassi di base viene costruita in questo modo:
CreateObject(classe,[nomeserver]) dove per "classe" si
intende il nome dell'applicazione e la classe dell'oggetto da creare. "Nomeserver"
è opzionale e indicherebbe il nome del server di rete su cui verrà creato
l'oggetto. Se è una stringa vuota (""), viene utilizzato il nome del
computer locale.
Per avvicinarsi ai
concetti, impostiamo un esempio per visualizzare un insieme di cartelle (folders):
Dim fs, f
'dichiarazione di variabili di tipo Variant
folderspec = "C:\"
'variabile che indica il percorso di cui visualizzare
le cartelle
Set fs = CreateObject("Scripting.FileSystemObject")
'assegnazione alla variabile "fs" dell"oggetto"
restituito dalla funzione CreateObject
Set f = fs.GetFolder(folderspec) 'assegnazione
alla variabile "f" dell'oggetto ottenuto tramite "fs" che col metodo
GetFolder restituisce un oggetto Folder corrispondente a una cartella nel
percorso specificato (folderspec = "C:\").
in questo esempio mancano le istruzioni di come fare per visualizzare le cartelle,
ma lo vedremo tra poco. Basandoci dunque su questo tipo di istruzioni,
ecco cosa possiamo realizzare:
Come si nota, è
presente una combobox che serve a selezionare l'unità di cui vogliamo
l'elenco delle cartelle, che appaiono nella ListBox sotto. Da questa è
possibile selezionare una cartella ed otterremo le sue sottocartelle
nella ListBox successiva, ed i file della cartella nella ListBox più grande
a destra. Se selezioniamo una sottocartella, otterremo nella ListBox a
destra l'elenco dei file della sottocartella selezionata. Mi fermo a questi
esempi, ma sarebbe possibile continuare a cercare tutte le sottocartelle che
vorremo con i relativi files. Lo scopo finale di quest'esercizio, oltre a
quello di vederne le istruzioni, è quello di ottenere nel contempo un elenco
delle cartelle e file selezionati, sul foglio di lavoro, in modo da crearsi
un database della composizione del nostro/i hard-disk. Una cosa del genere:
Il tutto è
migliorabile, ma lascio ai volenterosi il compito di apportarsi le
modifiche. Ma vediamo come lavorare:
Per prima cosa
provvediamo a "caricare" la Combobox con l'elenco delle unità di
memorizzazione presenti sul nostro computer (hard-disk, floppy, lettori CD,
ecc. ecc.) e sfrutteremo l'evento Activate dell'userform:
Private Sub
UserForm_Activate()
Dim fs, d, dc 'inizializiamo le variabili
Set fs = CreateObject("Scripting.FileSystemObject")
'usiamo CreateObject assegn. a fs
Set dc = fs.Drives 'impostiamo dc
come insieme dei drives (delle unità)
For Each d In dc 'per ogni d
(unità) nell'insieme dc (drives)
ComboBox1.AddItem d.DriveLetter
'aggiungiamo la lettera del drive "d" nella combo
Next
Set fs = Nothing 'poi si cancellano
le tre variabili dalla memoria
Set d = Nothing
Set dc = Nothing
End Sub |
in modo da ottenere
l'elenco da cui poter selezionare l'unità che ci interessa,
così............................................................................> |
|
Poi sfrutteremo l'evento Change della Combobox,
per caricare i nomi delle cartelle presenti nell'unità selezionata, come
elenco nella ListBox1
Private Sub
ComboBox1_Change()
On Error Resume Next 'usiamo il controllo
errori in quanto, selezionando una unità (il 'lettore di floppy
o un lettore CD), se vuoti, si genera un errore di run-time. In questo
'modo, sfruttando il codice errore, avvisiamo con un messaggio ed
usciamo dalla routine 'senza bloccare.
ListBox1.Clear 'puliamo la Listbox1
per il refresh (lista cartelle)
X = ComboBox1.Text 'usiamo una
variabile (la X) che rappresenta la lettera dell'unità 'selezionata,
concatenandola poi ai due punti e la backslash per formare la sintassi
giusta 'di identificativo unità, da assegnare alla variabile
folderspec
folderspec = "" & X & ":" & "\" & ""
'folderspec sarà ad esempio uguale a C:\
Label3.Caption = folderspec 'usiamo
la caption di una label posta sulla form, per 'indicare il percorso
selezionato
[b1].Value = "FILES IN " & Label3.Caption 'e
prepariamo nella cella B1 la scritta 'FILES IN + percorso come scritto
nella label
Dim fs, f, f1, fc 'dichiariamo le
variabili per le istruzioni relative al CreateObject
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.GetFolder(folderspec) 'vedi
spiegazioni nel primo esempio a inizio pagina
If Err.Number = 76 Then 'se si verifica
che l'unità è vuota, si genera questo errore che 'sfruttiamo per
avvisare col messaggio sotto
MsgBox "" & folderspec & " Unità vuota"
Exit Sub 'ed usciamo dalla routine
End If
Set fc = f.SubFolders 'impostiamo con "fc"
l'insieme delle cartelle (SubFolders) reperite 'con la variabile "f" (fs.GetFolder)
For Each f1 In fc ' per ogni
cartella (f1) presente in "fc"
ListBox1.AddItem f1.Name 'inseriamo
il nome cartella nella ListBox1
Next
Set fs = Nothing 'poi si cancellano
le tre variabili dalla memoria
Set f = Nothing
Set f1 = Nothing
Set fc = Nothing
Resume
End Sub
|
e dopo questa
operazione, troveremo l'elenco di tutte le cartelle presenti nell'unità
selezionata, nella nostra ListBox1. Non ho inserito in questo passaggio il
caricamento della ListBox2 dei nomi dei files presenti nell'unità
selezionata, perchè un elenco dei files in genere lo troviamo all'interno di
una cartella, e visto che vorremo memorizzare il contenuto di una cartella,
questo passaggio l'ho saltato. Basterà però vedere le istruzioni che seguono
qua sotto, per reperire le istruzioni necessarie ed integrarle nella routine sopra.
Il secondo
passaggio riguarda la selezione di una cartella nell'elenco della ListBox1,
in modo da ottenere un elenco di sottocartelle nella ListBox3 (quella in
basso a sinistra nella foto), e un elenco di file contenuti nella cartella
selezionata nella ListBox2 (la grande a destra). Contemporaneamente
otterremo che l'elenco delle sottocartelle venga scritto sul foglio di
lavoro nella colonna A, tante righe per quante saranno le sottocartelle, e a
partire dalla colonna B il nome dei files. In questo caso ho inserito un
ciclo che consente di riempire fino alla riga 62, e se il numero dei files
sono maggiori di 62, il ciclo si sposta nella colonna successiva,
continuando fino alla riga 62 e scalando ancora di colonna fino a che non
sia completato l'elenco dei files. Questa ultima operazione, in realtà non
era necessaria, bastava lasciarli inserire verso il basso solo nella colonna
B, ma l'ho inserita per far vedere come eventualmente occupare più colonne
nel caso si preferisca riempire verso destra anzichè solo verso il basso.
Queste comunque le istruzioni, che assegneremo all'evento Click della
ListBox1: (le istruzioni simili alle soprastanti non saranno commentate)
Private Sub
ListBox1_Click()
pulisci 'si chiama la macro
"pulisci" che serve a pulire tutte le celle del foglio di lavoro
ListBox2.Clear 'si pulisce la ListBox2 (quella dei files, a
destra)
ListBox3.Clear 'si pulisce la
ListBox3 (quella delle sottocartelle, in basso a destra)
unita = (ComboBox1.Text & ":" & "\") 'si
prende con "unita" l'unità selezionata
dire = ListBox1.Text 'con "dire"
leggiamo il nome della cartella selezionata
folderspec = (unita & dire & "\") 'con
folderspec componiamo il percorso
Label3.Caption = folderspec 'e
lo mostriamo nella Label3
[b1].Value = "FILES IN " & Label3.Caption
'vedi routine precedente
Dim fs, f, f1, fc, fd
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.GetFolder(folderspec)
Set fc = f.Files 'impostiamo con "fc"
l'insieme dei Files (nomi dei) reperiti con la variabile "f"
'(fs.GetFolder)
For Each f1 In fc ' per ogni
NomeFile (f1) presente in "fc"
ListBox2.AddItem f1.Name
'aggiungiamo il nome del file nella ListBox2
'sotto iniziamo la ricerca di una cella
libera, a partire dalla riga 2 (iRow = 2) e dalla 'colonna 2 (la B)(icol
= 2) usando il ciclo While... Wend, con la condizione che quando il
'numero riga sarà uguale a 62, incrementiamo di 1 il numero colonna
spostandoci quindi 'alla colonna successiva verso destra per
continuare a cercare celle libere. Modificando 'questi valori : iRow,
icol e 62 (limite riga inferiore) potrete decidere dove e come vorrete
'il vostro elenco files
Dim iRow, icol As Integer
iRow = 2
icol = 2
While Cells(iRow, icol).Value <> ""
iRow = iRow + 1
If iRow = 62 Then
iRow = 2
icol = icol + 1
End If
Wend
Cells(iRow, icol) = f1.Name 'nella cella
libera andrà il nome del vettore f1
Next 'continua il ciclo fino alla fine
degli f1.Name
'sotto: finito il ciclo per riportare i
nomi dei files nella ListBox2 e sul foglio di lavoro, 'iniziamo il
ciclo con l'assegnazione alla variabile "fd" non più dei nomi files
legati alla 'variabile "fc" (f.Files) , ma delle sottocartelle
presenti nella cartella selezionata, 'riempendo con i nomi trovati la
ListBox3 e la colonna A sul foglio di lavoro, e 'impostando il
carattere grassetto e il colore rosso ai nomi sul foglio.I commenti
sono i 'soliti visti appena sopra.
Set fd = f.SubFolders
For Each f1 In fd
ListBox3.AddItem f1.Name
iRow = 1
While Cells(iRow, 1).Value <> ""
iRow = iRow + 1
Wend
Cells(iRow, 1) = f1.Name
Cells(iRow, 1).Font.Bold = True
Cells(iRow, 1).Font.ColorIndex = 3
Next
Set fs = Nothing
Set fd = Nothing
Set f = Nothing
End Sub |
Con le spiegazioni
mi fermo qui perchè sarebbero ripetitive. Ovviamente sono presenti
istruzioni anche nell'evento Click della ListBox3, ma potrete scoprirle
scaricando il file. Se si volesse aggiungere una ListBox per sottocartelle
di sottocartelle, oppure usare le stesse ListBox facendo apparire il
contenuto delle sottocartelle (ListBox3) nella ListBox1 al posto delle
cartelle, dopo aver selezionato una cartella, in modo da usare le
sotto/sottocartelle nella ListBox3 e i relativi files nella ListBox2, un pò
come avviene con le vere DriveListBox, DirListBox e FileListBox . Ma
altrimenti che piacere vi lascerei, se proponessi tutto io? Uno sguardo alle
due macro "pulisci" e "puliscifile"
-
Sub pulisci:
-
Sub pulisci()
With ActiveSheet
.UsedRange.ClearContents 'con UsedRange
si puliscono tutte le celle con dati
.Cells(1, 1) = "CARTELLE" 'in A1 si
scrive la parola CARTELLE
.Cells(1, 2) = "FILES IN" 'in
B1 si scrive la parola FILES IN
End With
End Sub
-
Sub puliscifile
-
Sub puliscifile()
ult = [b2].End(xlToRight).Address 'con ult
prendiamo l'ultima colonna a destra occupata, riga 2
Set zonafile = Range([b1].End(xlDown), Range(ult))
'con zonafile reperiamo l'area da B1 all'ultima
zonafile.ClearContents
'cella in basso e fino a ult e puliamo.
With ActiveSheet
.Cells(1, 2) = "FILES IN" 'in B1 si
scrive la parola FILES IN
End With
End Sub
I fogli potranno
essere salvati come singoli fogli, in modo da formarsi un database dei
contenuti dell'hard-disk, e ovviamente potranno essere stampati.
File da scaricare
e consultare : ElencoFile2000.zip
26 Kb
Se invece vogliamo
caricare la lista dei nomi dei files presenti in una determinata cartella,
(sempre la solita), saranno necessarie minori istruzioni. Basta ovviamente
impostare nel codice il percorso che mira alla cartella, e poi decidere in
quale colonna e da quale riga iniziare ad importare i nomi dei
files. La routine è simile a quelle sopra, solo un pò più "alleggerita".
Poichè usiamo un
ciclo While per cercare una cella libera dove "scrivere" ogni nome di file
trovato nella cartella specificata, dovremo "pulire" le celle se vogliamo
che ogni volta che chiamiamo la macro, i nomi non si accodino a quelli
esistenti, caricati con lanci precedenti (altrimenti creeremmo solo dei
duplicati). Potremo anche sfruttare l'evento Open del Workbook, per lanciare
la macro all'apertura della cartella di lavoro. Vediamo la macro;
nell'esempio ho scelto di iniziare dalla cella A2, quindi riga 2, colonna 1:
(le istruzioni simili a quelle sopra non le commento)
Sub CaricaNomiFile()
Range([a2], [a2].End(xlDown)).ClearContents
'puliamo la zona con i nomi dei files
folderspec = ("C:\Temp\") 'con folderspec
indichiamo il percorso che mira alla cartella di cui 'vogliamo
l'elenco files, ognuno dovrà modificare secondo le proprie esigenze
Dim fs, f, Nomefile, Cartella
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.GetFolder(folderspec)
Set Cartella = f.Files
'sotto: si inizia il ciclo che per ogni
file (Nomefile) presente in Cartella
For Each Nomefile In Cartella
'sotto: iniziamo la ricerca di una cella
libera, a partire dalla riga 2 (iRow = 2) e dalla colonna 1 (la
'A)(icol = 1) usando il ciclo While... Wend
Dim iRow, icol As Integer
iRow = 2
icol = 1
While Cells(iRow, icol).Value <> ""
iRow = iRow + 1
Wend
Cells(iRow, icol) = Nomefile.Name 'nella
cella libera andrà il nome del file letto (per ogni...)
Next 'continua il ciclo fino alla fine
dei files presenti nella cartella scelta.
Set fs = Nothing
Set Cartella = Nothing
Set f = Nothing
End Sub |
e nell'evento Open
del Workbook, basterà chiamare il nome della macro, così:
Buon lavoro.
prelevato sul sito
www.ennius.altervista.org
|