Pchełki VBA – odcinek 7: listujemy zawartość folderu

https://xpil.eu/QrHRx

Dzisiejsza pchełka dotyczy operacji na plikach. Ponieważ operacje na plikach są tematem bardzo rozległym, a pchełki z założenia są maleńkie, musnę dziś tylko wierzchołek góry lodowej - a przy tej okazji pokażę jak iterować po elementach kolekcji.

Zadanie na dziś: napisać procedurę, która na wejściu przyjmuje dwa parametry: komórkę początkową oraz nazwę folderu, a w wyniku generuje nazwy wszystkich plików z zadanego folderu, do kolejnych komórek (w pionie), począwszy od tej zadanej.

Tradycyjnie zacznę od podania rozwiązania, a potem szczegółowo opiszę co się dzieje w kodzie.

Uruchamiamy Excela, przechodzimy do edytora VBA (Alt-F11), wstawiamy nowy moduł, w module umieszczamy następujący kod:

Option Explicit

Public Sub ListFiles(r As Excel.Range, p As String)
  Dim fso As Scripting.FileSystemObject
  Dim fld As Scripting.Folder
  Dim f As Scripting.File

  Set fso = New Scripting.FileSystemObject
  Set fld = fso.GetFolder(p)

  For Each f In fld.Files
    r.Value = f.Path
    Set r = r.Offset(1, 0)
  Next f
End Sub

 

UWAGA: aby powyższy kod poprawnie działał, musimy dodatkowo włączyć bibliotekę "Microsoft Scripting Runtime". W tym celu wchodzimy w menu Tools => References, przewijamy listę w dół aż znajdziemy pozycję "Microsoft Scripting Runtime", zaznaczamy ją, klikamy OK. Gotowe.

Najpierw sprawdźmy, czy to działa. Przechodzimy do okna poleceń (Ctrl-G) i wpisujemy tam:

ListFiles Range("A1"), "C:\Windows"

... i pukamy Enter. W efekcie powinniśmy dostać listę wszystkich plików z naszego folderu systemowego, w komórkach A1, A2 itd.

OK, teraz rzućmy okiem bardziej szczegółowo co w trawie piszczy.

Public Sub ListFiles(r As Excel.Range, p As String)

Tworzymy procedurę o nazwie ListFiles, z parametrami r (komórka początkowa) oraz p (folder, którego zawartość chcemy wylistować)

Dim fso As Scripting.FileSystemObject
Dim fld As Scripting.Folder
Dim f As Scripting.File

Deklarujemy trzy zmienne: fso typu FileSystemObject jest wymagane do jakichkolwiek działań na systemie plików za pomocą biblioteki Scripting, fld typu Folder to będzie nasz folder (albo katalog, jak zwał tak zwał), a f typu File - pojedynczy plik w tym katalogu.

Set fso = New Scripting.FileSystemObject

Inicjalizujemy dostęp do biblioteki Scripting (powyższa linijka będzie występować wszędzie tam, gdzie będziemy chcieli używać biblioteki Scripting). Nazwa fso to nic innego jak skrót od "File Scripting Object" czyli obiekt biblioteki Scripting. Reprezentuje on całą bibliotekę, wszystkie jej właściwości, procedury itd.

Set fld = fso.GetFolder(p)

Tu wywołujemy metodę GetFolder biblioteki Scripting, przekazując jej podaną przez użytkownika ścieżkę do folderu (zmienna p). Metoda ta zwraca obiekt typu Folder, reprezentujący cały folder (katalog). Na takim obiekcie możemy potem wykonywać różne czynności (odczytywać właściwości katalogu, zmieniać jego nazwę, skasować, wylistować zawartość itd.)

For Each f In fld.Files

Tu się odbywa magia właściwa, czyli iterujemy po kolekcji Files obiektu typu Folder.

Co to właściwie znaczy?

"Iterowanie po kolekcji" to uniwersalne określenie na pętlę, która wykona się tyle razy, ile elementów ma kolekcja, za każdym razem "wpisując" do zmiennej kontrolnej kolejny element kolekcji. W naszym przypadku do zmiennej f trafiać będą kolejne pliki, a następnie każdorazowo wykona się blok kodu między liniami "For Each ..." i "Next ..."

A czym jest kolekcja?

Kolekcja to pojęcie bardzo ogólne, oznacza nieuporządkowany zbiór elementów danego typu. Na każdej kolekcji, niezależnie od tego, jakiego typu obiekty ona przechowuje, można wykonać te same czynności: dodać obiekt do kolekcji, usunąć obiekt z kolekcji, policzyć ilość elementów kolekcji, wreszcie wykonać iterację po wszystkich elementach kolekcji.

W naszym konkretnym przypadku, iterujemy po elementach kolekcji Files, która jest standardowym elementem obiektu typu Folder, i która reprezentuje wszystkie pliki w folderze.

Przyjrzyjmy się teraz całej pętli:

For Each f In fld.Files
  r.Value = f.Path
  Set r = r.Offset(1, 0)
Next f

Każda iteracja będzie operowała na innym pliku, reprezentowanym przez zmienną f. Zmienna f pełni tutaj bardzo podobną rolę do zmiennej numerycznej, stosowanej w pętli typu For - zainteresowanych szczegółami odsyłam do http://xpil.eu/pchelki-vba-odcinek-4/ - tam omówiłem z grubsza kilka rodzajów pętli, w tym również For-Next.

No dobrze, wiemy już jak działa iteracja po kolekcji, a teraz zobaczmy co konkretnie robimy z każdym elementem naszej kolekcji fld.Files:

r.Value = f.Path
Set r = r.Offset(1, 0)

Najpierw wstawiamy wartość f.Path do komórki r (f.Path reprezentuje pełną ścieżkę do pliku, wraz z nazwą tego pliku na końcu), a następnie przesuwamy się komórką r oczko w dół.

Proste, prawda?

https://xpil.eu/QrHRx

Leave a Comment

Komentarze mile widziane.

Jeżeli chcesz do komentarza wstawić kod, użyj składni:
[code]
tutaj wstaw swój kod
[/code]

Jeżeli zrobisz literówkę lub zmienisz zdanie, możesz edytować komentarz po jego zatwierdzeniu.