Nie można wyświetlić nazwy folderu i jego ścieżki w języku VBA

Witam

Próbuję znaleźć "ścieżkę" folderu o podanej nazwie, aby zautomatyzować rzeczy w naszym biurze projektowym za pomocą solidworks.

Zaznaczam, że mam tylko nazwę pliku, a nie jego ścieżkę. 

powinno to wyglądać mniej więcej tak: F:\Business\??? \NazwaFolderu\...

Tylko na razie mogę się dowiedzieć, czy istnieje, ale nie po to, by odzyskać swoją ścieżkę, której potrzebuję na przyszłość. Mam tylko informację zwrotną "mam to" w konsoli

Macie jakieś pomysły?

Oto mój kod:

Funkcja FindFolder()

    Dim searchFolderName As Ciąg
    searchFolderName = "F:\Oferty"

    Dim FileSystem jako obiekt

    Set FileSystem = CreateObject("Scripting.FileSystemObject")

    doFolder FileSystem.GetFolder(nazwaFolderu_wyszukiwania)

 

Koniec subwoofera

Sub doFolder(Folder)
    Dim subFolder
    W przypadku błędu Wznów następny
    Dla każdego podfolderu w folderze Folder.SubFolders
        Jeśli subFolder.Name jak "NazwaFolderu", a następnie
            Debug.Print subFolder.Name, subFolder.GetPath
            Debug.Print ("rozumiem")
        Koniec
        Zakończ jeżeli:
        
        podfolder doFolder
    Następny podfolder

Koniec subwoofera

Dziękuję i życzę miłego dnia!

 

Ewan

 

Witam

Z jednej strony musisz poprawnie zadeklarować zmienną subFolder:

Dim subFolder As Scripting.Folder

A następnie sposobem na uzyskanie dostępu do ścieżki nie jest GetPath, ale Path:

Debug.Print subFolder.Name & subFolder.Path

 

Witaj Cyrylu,

 

Dziękuję za odpowiedź, właśnie zaktualizowałem kod... Rzeczywiście, wydaje się to bardziej logiczne!

Ale wynik niestety pozostaje taki sam...

 

 

Czy są włączone poświadczenia środowiska uruchomieniowego skryptów firmy Microsoft?

Ten kod działa dla mnie bardzo dobrze:

Sub FindFolder()

    Dim searchFolderName As String
    searchFolderName = "C:\test"

    Dim FileSystem As Object

    Set FileSystem = CreateObject("Scripting.FileSystemObject")

    doFolder FileSystem.GetFolder(searchFolderName)

End Sub

Sub doFolder(Folder)
    Dim subFolder As Scripting.Folder
    On Error Resume Next
    For Each subFolder In Folder.SubFolders
        If subFolder.Name Like "SW2020" Then
            Debug.Print subFolder.Name, subFolder.Path
            Debug.Print ("got it")
        End
        End If
        
        doFolder subFolder
    Next subFolder

End Sub

Całość jest wrażliwa na pękanie, więc należy zachować ostrożność. Jeśli i tak przejdzie przez Got It, to dlatego, że Jeśli działa, więc błąd jest gdzie indziej.

Tak, poświadczenia środowiska wykonawczego skryptów firmy Microsoft są włączone.

Właśnie zrobiłem test, aby spróbować przejść w górę ścieżki folderu "test", który utworzyłem w "C:\folder\test"

A więc mam:

 

searchFolderName = "C:\"

Jeśli subFolder.Name jak "test", to

 

Mam tylko "got it" z konsoli, nie nazwę, ani ścieżkę

Zwróciłem uwagę na pęknięcie, jak wskazujesz

 

 

Oczywiście działa na niektórych plikach, ale nie na wszystkich... podczas gdy wszystkie znajdują się w tym samym folderze nadrzędnym i szanuję wcięcie

Szczerze żartowniś, nie widzę w czym problem. Świetnie sprawdza się w domu

To szaleństwo tej historii...

Na przykład działa na F:\Business\ADIDAS, ale nie na F:\Business\ADOPT

 

Może sekwencja, która sprawia problemy.

Korzystając z funkcji tego typu, trzeba pomyśleć o opróżnieniu pamięci. Spróbuję ustawić FileSystem = nothing:Set Subfolder = Nothing  tuż przed końcem, który jest w sekcji "Rozumiem"

The Set FileSystem = Nothing oczywiście do niego nie przemawia.

Dodałem  Set subFolder = Nic , nic to nie zmienia

 

 

Cyryl

Wygląda jednak na to, że miałeś rację, kiedy uruchamiam kod dla pierwszych folderów, działa on idealnie. Ale nie na kolejne... Trzeba powiedzieć, że serwer jest załadowany.

Może spróbuj suba wyjściowego zamiast End. Następnie umieść Set FileSystem = Nothing w głównej procedurze w zasadzie:

Sub FindFolder()
    
    Dim searchFolderName As String
    searchFolderName = "C:\test"

    Dim FileSystem As Scripting.FileSystemObject

    Set FileSystem = CreateObject("Scripting.FileSystemObject")

    doFolder FileSystem.GetFolder(searchFolderName)

    Set FileSystem = Nothing

End Sub

Sub doFolder(Folder)
    Dim subFolder As Scripting.Folder
    On Error Resume Next
    For Each subFolder In Folder.SubFolders
        If subFolder.Name Like "SW2020" Then
            Debug.Print subFolder.Name, subFolder.Path
            Debug.Print ("got it")
            Set subFolder = Nothing
        exit sub
        End If
        
        doFolder subFolder
    Next subFolder

End Sub

 

Nie działa lepiej, sub wyjściowy na razie całkowicie go zawiesza :/

 

Witam

Wykonaj test bez warunku if i zobacz wydruki zwrócone w każdej pętli.

Przetestuj również

Debug.Print subFolder.Name
Debug.Print subFolder.Path
Debug.Print ("got it")

 

Dobry wieczór wszystkim,

Najnowsza wersja kodu działa poprawnie. Aż do momentu, w którym szukasz folderu znajdującego się bardzo daleko w drzewie...
Jeśli podczas wyszukiwania natkniesz się na folder systemowy (taki jak Informacje o woluminie systemowym), procedura wyszukiwania zbacza z torów: zwraca niezdefiniowane podfoldery bez nazw, ale zwraca wartość "True" podczas testowania zgodności z nazwą wyszukiwania. Stąd pusty ciąg i fałszywy wynik.
Atrybuty nadrzędnego folderu systemowego nie wskazują na konkretny status: wartość 22, czyli katalog, ukryty i systemowy, nic niezwykłego.
Zauważ, że są to te same atrybuty, co dla katalogu głównego dysku ("D:\"), co nie stanowi problemu.

Aby obejść pb, nie znalazłem innego rozwiązania, jak tylko przetestować liczbę podfolderów (nb = Folder.SubFolders.Count) przed pętlą wyszukiwania i zakończyć procedurę, jeśli spowoduje to błąd (70). W oryginalnym kodzie wznawianie w przypadku błędu wznawiania następnego ukrywa błąd.

Dodałem również wartość logiczną, która pozwala zatrzymać wyszukiwanie po znalezieniu folderu. Przetestuj, który będzie musiał zostać usunięty, jeśli w wyszukiwaniu może znajdować się kilka folderów o tej samej nazwie...

Option Explicit

Dim bFindFldr As Boolean

'==============================================================='
Sub FindFolder()
    
            Dim searchFolderName As String
            Dim FileSystem As Scripting.FileSystemObject
    
    searchFolderName = "D:\"
    Set FileSystem = CreateObject("Scripting.FileSystemObject")
    bFindFldr = False
    
    If Not bFindFldr Then doFolder FileSystem.GetFolder(searchFolderName)

    Set FileSystem = Nothing
    Debug.Print ("Fin de la recherche")

End Sub

'==============================================================='
Sub doFolder(Folder As Object)
            Dim subFolder As Scripting.Folder
            Dim nb As Integer

    On Error GoTo erreur
    nb = Folder.SubFolders.Count
    For Each subFolder In Folder.SubFolders
        If Not (subFolder.Attributes And System) Then

            If Not bFindFldr Then                         ' Si le dossier n'a pas encore été trouvé...
                If subFolder.Name Like "ACER" Then
                    Debug.Print subFolder.Name, subFolder.Path
                    Debug.Print ("got it")
                    bFindFldr = True
                End If
                If Not bFindFldr Then doFolder subFolder      ' Poursuite récursive de la recherche si le dossier n'est pas trouvé
            Else
                Debug.Print ("     - Dépilage:   " & subFolder.Path)   ' Permet d'afficher le "dépilage" des fonctions toujours activées après avoir trouvé le dossier
            End If
        End If
    Next subFolder
    Exit Sub
erreur: Debug.Print ("     *** Dossier système ***  " & Folder.Path)
End Sub

Pozdrowienia.

1 polubienie

Witaj m.blt,

 

Dziękuję za szczegółową odpowiedź, to bardzo interesujące! Udało mi się przetestować twój kod i działa dobrze na moim dysku C.

Mam jednak ten sam problem na serwerze, gdy szukam odległego folderu w drzewie.

Myślę, że pamięć się nasyca...

Może mógłbym ograniczyć wyszukiwanie w określonym typie folderu?

Na przykład wiem, że jeśli nazwa mojej firmy to AD006, to folder nadrzędny jest nazwą klienta i dlatego zaczyna się od litery A.

Coś takiego:

Jeśli subFolder.Name jak "A*", to

Co myślisz?

Przydatne może być sprawdzenie liczby znaków w łańcuchu ścieżek, aby dowiedzieć się, czy to limit długości ścieżki ciągu jest problemem, czy coś zupełnie innego.

Kolejna rzecz do wypróbowania; Zezwalaj systemowi Windows na obsługę dłuższych ścieżek:

W edytorze rejestru przejdź do HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled , zmień jego wartość na 1 i uruchom ponownie.

1 polubienie

Dobry wieczór

Ryzyko przepełnienia stosu wykonawczego VBA jest aspektem, który należy wziąć pod uwagę w przypadku procedury rekurencyjnej, takiej jak doFolder makra.
O ile się nie mylę, w tym przypadku wyszukiwania folderu na dysku liczba jednoczesnych połączeń jest co najwyżej równa liczbie folderów o najdłuższej ścieżce istniejącej w drzewie katalogów. To znaczy kilka jednostek, a nawet kilkadziesiąt, prawdopodobnie nie więcej. W każdym razie jest mało prawdopodobne, aby spowodowało to przepełnienie, przepełnienie, które byłoby sygnalizowane przez błąd.

Mówiąc o błędach: podczas opracowywania makra instrukcja On Error Resume Next musi zostać usunięta , co skutkuje ukryciem błędów poprzez ciche kontynuowanie wykonywania w wierszu następującym po błędzie. Możesz to sprawdzić już w pierwszej wersji makra: wystąpił błąd (70: odmowa uprawnień), a spojrzenie na właściwość Folder.path w tym momencie daje winowajcę: Informacje o woluminie systemowym.

Jeśli problem na twoim serwerze jest tego samego rodzaju, co na dysku C:, tj. folderze, który nie jest dostępny, być może dzięki temu prostemu sposobowi będziesz w stanie go zidentyfikować, pozwalając na wystąpienie błędu w czasie wykonywania...

Jeśli chodzi o prowadzenie badań tylko nad częścią nazwy, nie wydaje mi się, aby przynosiło to znaczące korzyści.
Może to być poprawa szybkości przetwarzania, gdy makro będzie działać we wszystkich przypadkach.

Pozdrowienia.


explorateurdd.png

m.blt, Sylk,

Dziękuję za poświęcenie czasu, aby mi pomóc.

Panie BLT, rzeczywiście wydaje się to logiczne. Nie mam instrukcji On Error Resume Next , ponieważ używam kodu, który opublikowałeś powyżej.

Niestety, nie mogę pobrać folderu , który powoduje problem, ponieważ VBA ulega całkowitej awarii podczas uruchamiania na F:\, gdy przekraczam pierwsze 4 lub 5 folderów...

Jeśli chodzi o filtrowanie według litery, inna opcja: ograniczyć wyszukiwanie do pierwszego podfolderu?  Nie muszę iść dalej i uniemożliwiłoby mi to natknięcie się na foldery z odmową uprawnień? Jeśli chodzi o F:\Business, którego szukam, zwykle mam do tego wszelkie prawa.

Sylk, zamierzam zmienić klucz rejestru i spróbować ponownie.

 

Ewan

Panie BLT, po kilku próbach w końcu udaje mi się uzyskać informację zwrotną w terminalu! Rzeczywiście, są foldery systemowe lub foldery, do których nie mam praw!! Gdy tylko kod napotka jeden, ulega całkowitemu awarii.

Sylk, klucz rejestru był już w True!