Obtenir les chemins des dossiers spéciaux Windows
Imaginez qu’en VBA vous ayez besoin de créer un fichier sur le bureau Windows de l’utilisateur. La première solution consiste à créer un fichier à cet emplacement :
C:\Users\IDENTIFIANT\Desktop\monfichier.txt
. Oui, mais :
- L’identifiant varie en fonction de l’utilisateur connecté.
- Les chemins ne sont pas les mêmes selon votre version de Windows. Par exemple, sur XP, le chemin serait plutôt :
C:\Documents and Settings\IDENTIFIANT\Bureau\monfichier.txt
.Comment gérer tout ça proprement ?
(sujet proposé par Denis Scheidt, auteur de la bibliothèque libMAIL)
Le principe
Une chose est sûre : coder les chemins d’accès « en dur » est une mauvaise idée. Vous obtiendriez une application Access difficile à déplacer.
Par chance – à moins que ce soit fait exprès ? 😉 – les API Windows fournissent des fonctions pour obtenir le chemin d’un certain nombre de dossiers spéciaux comme « Documents » (ou « Mes documents » sur Windows XP), « Programmes » (ou « Program Files« ), « Bureau« , etc.
Le code
Voici un bout de code VBA à recopier dans un module standard de votre base Access.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
' CONSTANTES POUR SpecialFolders ' Dossier Programmes du menu Démarrer Public Const CSIDL_PROGRAMS As Long = 2 ' Mes documents (ou Documents sur Vista/7/8) Public Const CSIDL_PERSONAL As Long = 5 ' Favoris Public Const CSIDL_FAVORITES As Long = 6 ' Dossier Démarrage du menu Démarrer Public Const CSIDL_STARTUP As Long = 7 ' Documents récents Public Const CSIDL_RECENT As Long = 8 ' Dossier "Envoyer vers" Public Const CSIDL_SENDTO As Long = 9 ' Dossier du menu Démarrer Public Const CSIDL_STARTMENU As Long = 11 ' Bureau Public Const CSIDL_DESKTOP As Long = 16 ' Raccourcis Réseau Public Const CSIDL_NETHOOD As Long = 19 ' Dossier des modèles de documents Public Const CSIDL_TEMPLATES As Long = 21 ' Menu Démarrer commun Public Const CSIDL_COMMON_STARTMENU As Long = 22 ' Dossier commun Programmes du menu Démarrer Public Const CSIDL_COMMON_PROGRAMS As Long = 23 ' Dossier commun Démarrage du menu Démarrer Public Const CSIDL_COMMON_STARTUP As Long = 24 ' Bureau commun (public) Public Const CSIDL_COMMON_DESKTOP As Long = 25 ' Dossier Applications (AppData) Public Const CSIDL_APPDATA As Long = 26 ' Raccourcis Imprimantes Public Const CSIDL_PRINTHOOD As Long = 27 ' Favoris communs Public Const CSIDL_COMMON_FAVORITES As Long = 1 ' Dossier des fichiers Internet temporaires Public Const CSIDL_INTERNET_CACHE As Long = 32 ' Cookies Public Const CSIDL_COOKIES As Long = 33 ' Historique de navigation Public Const CSIDL_HISTORY As Long = 34 ' Program Files Public Const CSIDL_PROGRAMS_FILES As Long = 38 ' FONCTIONS API Declare Function SHGetSpecialFolderLocation _ Lib "shell32" ( _ ByVal hwnd As Long, _ ByVal folderid As Long, _ shidl As ITEMIDLIST) _ As Long Declare Function SHGetPathFromIDList _ Lib "shell32" _ Alias "SHGetPathFromIDListA" ( _ ByVal shidl As Long, _ ByVal shPath As String) _ As Long ' STRUCTURES POUR SpecialFolders Type SHITEMID SHItem As Long itemID() As Byte End Type Type ITEMIDLIST shellID As SHITEMID End Type ' --- ' CHEMIN D'UN DOSSIER SPECIAL ' --- Function DossierSpecial(lngDossier As Long) As String Dim strChem As String, dtuID As ITEMIDLIST, lngRes As Long ' Chercher le Bureau virtuel. lngRes = SHGetSpecialFolderLocation(0&, lngDossier, dtuID) If lngRes = 0 Then ' Pas d'erreur... strChem = String$(512, Chr$(0)) lngRes = SHGetPathFromIDList(ByVal dtuID.shellID.SHItem, _ ByVal strChem) If lngRes Then DossierSpecial = Left$(strChem, _ InStr(strChem, Chr$(0)) - 1) End If End Function |
Si vous avez Access 2000 ou plus
Le langage VBA d’Access permet de définir des énumérations à partir d’Access 2000. Ce qui peut simplifier votre saisie. Par conséquent, si vous avez Access 2000 ou plus, ajoutez ceci au code précédent (vous pouvez par exemple l’insérer après le dernier End Type
) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
' Enumérations pour Access 2000+ Public Enum Dossier DemarrerProgrammes = CSIDL_PROGRAMS Documents = CSIDL_PERSONAL Favoris = CSIDL_FAVORITES DemarrerDemarrage = CSIDL_STARTUP DocumentsRecents = CSIDL_RECENT EnvoyerVers = CSIDL_SENDTO Demarrer = CSIDL_STARTMENU Bureau = CSIDL_DESKTOP RaccourcisReseau = CSIDL_NETHOOD Modeles = CSIDL_TEMPLATES DemarrerCommun = CSIDL_COMMON_STARTMENU DemmarrerProgrammesCommun = CSIDL_COMMON_PROGRAMS DemarrerDemarrageCommun = CSIDL_COMMON_STARTUP BureauCommun = CSIDL_COMMON_DESKTOP Application = CSIDL_APPDATA RaccourcisImprimantes = CSIDL_PRINTHOOD FavorisCommuns = CSIDL_COMMON_FAVORITES FichierInternetTemporaires = CSIDL_INTERNET_CACHE Cookies = CSIDL_COOKIES Historique = CSIDL_HISTORY Programmes = CSIDL_PROGRAMS_FILES End Enum |
Tester sur Access 97
Vous pouvez la tester directement dans la fenêtre Exécution :
- Faites apparaître la fenêtre Exécution (
CTRL
+G
). - Tapez quelque chose comme :
? DossierSpecial(CSIDL_DESKTOP)
- Appuyez sur
[Entrée]
pour valider.
Vous devriez obtenir le chemin de votre bureau Windows. Sur ma machine :C\:Users\Hervé\Desktop
.
Bien sûr, vous pourriez aussi taper : ? DossierSpecial(16)
pour obtenir le même résultat. Mais l’intérêt des constantes est d’éviter de mémoriser leurs équivalents numériques. 😉
Tester sur Access 2000 et plus
Si vous avez Access 2000 ou plus, et que vous avez recopié l’énumération Dossier
dans votre base, vous pouvez aussi faire comme ceci :
- Faites apparaître la fenêtre Exécution (
CTRL
+G
). - Tapez quelque chose comme :
? DossierSpecial(Dossier.Bureau)
- Appuyez sur
[Entrée]
pour valider.
Vous profiterez de l’auto-complétion dès que vous aurez tapé « Dossier.
»
lngDossier As Long
par lngDossier As Dossier
dans le code plus haut. L’auto-complétion sera déclenchée dès la parenthèse ouvrante !
En pratique
Maintenant, si en VBA vous devez créer un fichier dans le dossier « Documents » de l’utilisateur, il vous suffit de commencer par :
1 2 3 4 5 |
Sub Test() Dim strChemin As String strChemin = DossierSpecial(Dossier.Documents) & "monfichier.txt" ' ... suite du traitement End Sub |
leporello > Dans ce cas, il ne s’agit plus d’un dossier spécial (au sens « Dossier standard défini par le système »). Donc il faut connaître son chemin, et écrire quelque chose comme :
Si le chemin est susceptible de changer (et ça va être forcément le cas), une constante peut améliorer la maintenance :
Bonjour,
Remarquable aide pratique!
Mais comment « adresser » un dossier sur un autre disque ex: D:Mes Documents?
Vous êtes génial … Comme toujours 😉