Impossible d'afficher un nom de dossier et son chemin en VBA

Bonjour,

Je cherche à trouver le "path" d'un dossier à partir d'un nom donné pour automatiser des choses dans notre BE avec solidworks.

Je précise que je n'ai que le nom du dossier et pas son chemin. 

celà doit ressembler à quelque chose comme : F:\Affaires\???\NomDuDossier\...

Seulement pour le moment, j'arrive à trouver si il existe mais pas a récupérer son chemin d'accès, dont j'ai besoin pour la suite. Je n'ai dans la console que le retour "got it"

Avez vous des idées?

Voici mon code :

Sub FindFolder()

    Dim searchFolderName As String
    searchFolderName = "F:\Affaires"

    Dim FileSystem As Object

    Set FileSystem = CreateObject("Scripting.FileSystemObject")

    doFolder FileSystem.GetFolder(searchFolderName)

 

End Sub

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

End Sub

Merci et bonne journée!

 

Ewan

 

Bonjour,

D'une part il faut déclarer correctement la variable subFolder:

Dim subFolder As Scripting.Folder

Et ensuite le moyen d'accéder au chemin n'est pas GetPath mais Path:

Debug.Print subFolder.Name & subFolder.Path

 

Bonjour Cyril,

 

Merci pour ta réponse, je viens de mettre le code à jour... effectivement ça semble plus logique!

Mais le résultat reste malheureusement le même...

 

 

Est-ce que les références Microsoft Scripting Runtime sont bien activées?

Ce code là fonctionne très bien chez moi:

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

L'ensemble est sensible à la casse donc bien faire attention. Si ça passe par Got It de toute façon c'est que le If fonctionne donc l'erreur est ailleurs.

Oui les les références Microsoft Scripting Runtime sont activées.

Je viens de faire un essai pour essayer de remonter le path du dossier "test" que j'ai crée sous "C:\dossier\test"

donc j'ai :

 

searchFolderName = "C:\"

et 

If subFolder.Name Like "test" Then

 

je n'ai que "got it" en sortie de console, pas le nom, ni le path

j'ai fait attention à la casse comme tu l'indique

 

 

Visiblement ça fonctionne sur certains dossiers, mais pas tous... alors qu'ils sont tous dans le même dossier parent et que je respecte l'indentation

Franchement joker, je ne vois pas où est le problème. Fonctionne très bien chez moi

C'est dingue cette histoire...

Exemple ça fonctionne sur F:\Affaires\ADIDAS mais pas sur F:\Affaires\ADOPT

 

Peut-être l'enchaînement qui pose problème.

Faut penser à vider la mémoire lorsque l'on fait appel à des fonctions de ce type. Je tenterai bien un Set FileSystem = nothing:Set SubFolder = Nothing  juste avant le end qui est sous "Got It"

Le Set FileSystem = Nothing ne lui plait pas visiblement.

J'ai ajouté le  Set subFolder = Nothing ça ne change rien

 

 

Cyril,

il semble que tu ai vu juste cependant, quand j'execute le code pour les premier dossiers ça fonctionne parfaitement. Mais pas pour les suivants... il faut dire que le serveur est chargé.

Peut-être tenter un exit sub au lieu de End. Puis mettre le Set FileSystem = Nothing dans la procédure principale en gros:

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

 

ça ne fonctionne pas mieux, le exit sub le plante complètement pour le coup :/

 

Bonjour

Fais le test sans la condition if et vois les print retournés à chaque loop.

Tester aussi

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

 

Bonsoir à tous,

La dernière version du code fonctionne bien. Jusqu'au moment où on recherche un dossier situé très loin dans l'arborescence...
Au cours de la recherche, si on rencontre un dossier système (du type System Volume Information), la procédure de recherche déraille: elle renvoie des sous-dossiers indéfinis et sans noms, mais retourne une valeur "True" au test de la conformité avec le nom recherché. D'où une chaîne vide et un résultat faux.
Les attributs du dossier système parent n'indiquent pas un statut particulier : valeur égale à 22, à savoir répertoire, caché et système, rien d'inhabituel.
A noter que ce sont les mêmes attributs que pour la racine du disque ("D:\") qui ne pose aucun problème.

Pour contourner le pb, je n'ai pas trouvé d'autre solution que de tester le nombre de sous-dossiers (nb = Folder.SubFolders.Count) avant la boucle de recherche, et de quitter la procédure s'il provoque une erreur (70). Dans le code original, le On Error Resume Next masque l'erreur.

J'ai également ajouté un booléen qui permet de stopper la recherche une fois que le dossier a été trouvé. Test qu'il faudra supprimer s'il peut exister plusieurs dossiers du même nom dans la recherche...

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

Cordialement.

1 « J'aime »

Bonjour m.blt,

 

Merci pour ta réponse détaillée, c'est très intéressant! J'ai pu tester ton code et il fonctionne correctement sur mon disque C.

Cependant j'ai le même genre de souci sur le serveur lorsque je cherche un dossier éloigné dans l'arborescence.

Je pense que la mémoire sature...

Peut être pourrais-je limiter la recherche dans un certains type de dossier?

Par exemple je sais que si mon nom d'affaire est AD006 alors le dossier parent est le nom du client et donc commence par A.

Quelque chose comme :

If subFolder.Name Like "A*" Then

Qu'en penses-tu?

Il pourrait être utile de vérifier le nombre de caractères de la chaîne des chemins, histoire de savoir si c'est la limite de longueur du string path qui pose problème ou toute autre chose.

Autre chose à essayer ; autoriser Windows à gérer des longueurs de chemins plus importantes :

Dans l'éditeur de registre aller à HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled , passer sa valeur à 1 et rebooter.

1 « J'aime »

Bonsoir,

Le risque d'un débordement de la pile d'exécution de VBA est un aspect à considérer dans le cas d'une procédure récursive comme le doFolder de la macro.
Sauf erreur de ma part, dans ce cas de recherche d'un dossier sur un disque, le nombre d'appels simultanés est au plus égal au nombre de dossiers du plus long chemin existant dans l'arborescence des répertoires. Soit quelques unités, voire quelques dizaines, probablement pas davantage. En tout cas pas de nature à provoquer un débordement, débordement qui serait signalé par une erreur.

A propos d'erreur: pendant la mise au point de la macro, il faut supprimer l'instruction On Error Resume Next qui a pour effet de masquer les erreurs en continuant l'exécution en silence à la ligne suivant l'erreur. Vous pouvez d'ailleurs le vérifier sur la toute première version de votre macro: une erreur se produit (70: permission refusée), et la consultation à ce stade de la propriété Folder.path vous donne le coupable: System Volume Information.

Si le problème sur votre serveur est de même nature que sur le disque C:, c'est à dire un dossier non accessible, c'est peut-être par ce moyen simple que vous le pourrez l'identifier, en laissant se produire l'erreur à l'exécution...

Quant à faire la recherche sur une partie seulement du nom, ça ne me paraît pas devoir apporter un gain significatif.
Il pourra s'agir d'une amélioration de la rapidité de traitement, une fois la macro fonctionnelle dans tous les cas.

Cordialement.


explorateurdd.png

m.blt, Sylk,

Merci de prendre de votre temps pour m'aider.

m.blt, effectivement ça semble logique. Je n'ai pas l'instruction On Error Resume Next car j'utilise le code que tu as posté ci-dessus.

Je ne peux malheureusement pas avoir le dossier qui pose souci en erreur car VBA plante complètement lors de l'execution sur F:\ lorsque je dépasse les 4 ou 5 premier dossiers...

Pour ce qui est du filtrage par lettre, une autre option : limiter la recherche au premier sous dossier?  je n'ai pas besoin d'aller plus loin et ça m'éviterais de tomber sur des dossier avec permission refusé? Pour ce qui est du F:\Affaires sur lequel je cherche, normalement, j'ai tout les droits.

Sylk, je vais modifier la clef de registre et essayer de nouveau.

 

Ewan

m.blt, après plusieurs essais, j'arrive enfin à avoir des retours dans le terminal! effectivement il y'a des dossiers system ou des dossiers pour lequels je n'ai pas les droits!!! dès que le code en rencontre un, il se plante complètement..

Sylk, la clef de registre était déjà en True!