Wyszukiwanie podfolderów w folderze roboczym.
W celach testowych utworzyłem przykładowy folder MyFiles, który umieściłem na dysku C:\
Pełna ścieżka dostępu do tego folderu ma postać: "C:\MyFiles\". Folder ten zawiera podfoldery i pliki o przeróżnych
(czasami bardzo dziwnych) nazwach i różnych atrybutach.
W sumie folder roboczy zawiera 24 pliki znajdujące się w 8 podfolderach.
Pierwszym celem będzie znalezienie tych 8 podfolderów. Jeżeli uda się odczytać wszystkie nazwy 8 podfolderów w folderze roboczym,
to następnym etapem będzie znalezienie wszystkich 24 plików.
• Wbudowana funkcja Dir
Najprostszym rozwiązanie jest skorzystanie z wbudowanej funkcji Dir, która zwraca wartość typu String reprezentującą nazwę pliku, katalogu lub folderu, która odpowiada określonemu wzorcowi, atrybutowi pliku albo etykiecie dysku.
Dir[(nazwa_ściezki[, atrybuty])]
Lista podfolderów zwracanych przez funkcję Dir ()
Najprostsza postać procedury zwracającej nazwy podfolderów w folderze roboczym ma postać:
Public Function ListSubFolders() Dim sDirName As String Const conFolderName As String = "C:\MyFiles\" ' On Error Resume Next sDirName = Dir(conFolderName, vbDirectory) ' przeszukuj folder roboczy w poszukiwaniu podfolderów Do Until sDirName = "" ' jeżeli zwracana ścieżka jest folderem If (GetAttr(conFolderName & sDirName) And vbDirectory) = vbDirectory Then ' pomiń katalog bieżący "." i nadrzędny ".." If StrComp(sDirName, ".", vbBinaryCompare) <> 0 And _ StrComp(sDirName, "..", vbBinaryCompare) <> 0 Then ' pokaż w oknie "Immediate" Debug.Print conFolderName & sDirName End If End If ' pobierz następny element (plik lub folder) sDirName = Dir() Loop End Function
Niestety. Po wywołaniu funkcji ListSubFolders () Access zgłasza błąd i pokazuje tylko 3 znalezione foldery:
Jeżeli odremujemy instrukcję On Error Resume Next, to uzyskamy nieco bogatszą, ale nieprawidłową listę podfolderów o niewiele mówiących nazwach zawierających znaki ???
Na liście znajduje się pozycja C:\MyFiles\Ola??ma?kota.txt (czwarta od góry). Powodowała ona błąd po uruchomieniu funkcji ListSubFolders () bez instrukcji On Error Resume Next. Faktycznie nie jest folder, ale plik tekstowy o Unicodowej nazwie Ola作手ma册kota.txt, z nazwą którego funkcja Dir nie daje sobie rady. Ostatnia pozycja C:\MyFiles\??????, odnosząca się do folderu niewiele mówi. Folderów o takich zwracanych nazwach, może być wiele w folderze roboczym.
Wniosek jest prosty. Wbudowana funkcja Dir nie daje sobie rady z odczytaniem nazw podfolderów w „moim wydumanym” folderze roboczym.
Komenda (polecenie) DIR uruchamiana za pomocą funkcji Shell(...)
Podstawowe informacje o komendzie Dir możemy uzyskać po uruchomieniu w oknie „Immediate” za pomocą wbudowanej funkcji Shell, poniższej instrukcji:
?Shell(Environ$("COMSPEC") & " /k Dir/?", vbMaximizedFocus)
' lub bardziej skrótowo:
?Shell("cmd.exe /k Dir/?", vbMaximizedFocus)
Aby otworzyć okno „Immediate”, należy wcisnąć klawisze Ctrl+G. Można też w edytorze kodu VBA wybrać polecenie „View/Immediate Window”.
Liczba 4880 jest identyfikatorem zadania PID zwracanym przez funkcję
Shell.
Identyfikator ten jednoznacznie określa wykonujący się program.
Po uruchomieniu komendy Dir za pomocą funkcji Shell zostaje otwarte okno z podstawowymi informacjami
dotyczącymi komendy Dir.
Lista podfolderów zwracanych przez komendę Dir ()
Poznaliśmy „najsubtelniejsze” tajniki komendy Dir, wię możemy spróbować uzyskać listę podfolderów znajdujących się w folderze roboczym. Wystarczy w oknie „Immediate” wpisać poniższą instrukcję i podziwiać wynik:
?Shell(Environ$("COMSPEC") & " /k Dir C:\MyFiles\* /A:D /B /S",vbMaximizedFocus)
- Shell
- wywołanie funkcji Shell
- Environ$
- funkcja zwracająca zmienne środowiskowe
- "COMSPEC"
- zmienna środowiskowa ComSpec (ściżka do interpretera poleceń cmd.exe systemu Windows)
- /k
- przełącznik polecena cmd. Po wykonaniu polecenia okno interpretera poleceń cmd.exe pozostaje otwarte
- Dir
- wywołanie funkcji Dir
- C:\MyFiles\*
- ścieżka do folderu roboczego, wraz z wieloznacznikiem "*"
- /A:D
- (A:) atrybut D nakazuje wyszukiwanie tylko folderów
- /B
- nakazuje użycia prostego formatu (bez informacji nagłówka lub podsumowania)
- /S
- nakazuje wyświetlanie wszystkich plików i folderów w określonym katalogu i wszystkich podkatalogach
vbMaximizedFocus
- otwarte okno ma mieć fokus i być zmaksymalizowane
Po uruchomieniu instrukcji wyszukiwania podfolderów w oknie „Immediate” otrzymujemy poniższą listę podfolderów:
Lista znalezionych podfolderów
Na liście tej znajdują się wszystkie podfoldery z folderu roboczego. Niestety, w niektórych przypadkach zwrócone nazwy nie odzwierciedlają faktycznych nazw podfolderów. Także próba przekierowania zwracanego strumienia przez wywołaną instrukcję do pliku tekstowego ~Dir2File.txt nic nie daje.
?Shell(Environ$("COMSPEC") & " /c Dir C:\MyFiles\* /A:D /B /S > C:\MyFiles\~Dir2File.txt")
Otrzymujemy plik z tekstem o stronie kodowej IBM-852,
Lista znalezionych podfolderów
którego treść po przekonwertowaniu na stronę kodową 1250 jest identyczna z tekstem zwróconym w oknie poleceń.