Get the Path to My Documents in VBA

VBA has an Environ function. To get a list of all the Environ variables you can see, you can use the method at VBA Express. I use the USERPROFILE argument like this

You can also use the Windows API as described at My Documents + Environment Variables

23 thoughts on “Get the Path to My Documents in VBA

  1. One can also look up Excel VBA help for ‘environ’ (w/o the quotes) and get pretty exhaustive information including what I suspect is the “base” code for most examples one finds on various websites.

  2. Your code gives an incorrect answer on my system. It returns “C:Documents and SettingsusernameMy Documents”, but that folder doesn’t exist on this computer. I have the “My Documents” folder on a different drive than the username folder. In fact, I don’t have a folder called “My Documents” anywhere. But, I can click on the “My Documents” folder that is on my desktop and it will show me the same files as if I navigated directly to “D:username”.

    I did a quick search for an environment variable that would expose where this desktop folder actually points to, but I came up empty-handed.

  3. Environ is okay for some directory lookups, but to get them all, reliably, you need to use Windows APIs:

    Private Declare Function lstrlenW Lib “kernel32” _
        (ByVal lpString As Long) As Long

    Private Declare Function SHGetFolderPath Lib “shfolder.dll” _
        Alias “SHGetFolderPathA” _
        (ByVal hwndOwner As Long, _
        ByVal nFolder As Long, _
        ByVal hToken As Long, _
        ByVal dwReserved As Long, _
        ByVal lpszPath As String) As Long

    Function MyDocumentsDir()
        Dim sBuffer As String
        sBuffer = Space$(260)
        If SHGetFolderPath(&H0, &H5, -1, &H0, sBuffer) = 0 Then
            MyDocumentsDir = Left$(sBuffer, lstrlenW(StrPtr(sBuffer)))
        End If
    End Function

  4. Another way using Wscript:

    Function GetSpecialFolderNames()
    Dim objFolders As Object
    Set objFolders = CreateObject(“WScript.Shell”).SpecialFolders

    MsgBox objFolders(“desktop”)
    MsgBox objFolders(“allusersdesktop”)
    MsgBox objFolders(“sendto”)
    MsgBox objFolders(“startmenu”)
    MsgBox objFolders(“recent”)
    MsgBox objFolders(“favorites”)
    MsgBox objFolders(“mydocuments”)
    End Function

  5. I had the environ function in my notes for a rainy day, can’t remember why I Googled it in the first place. being in application support where I get to tinker with all sorts of software I’m always interested in finding the ‘joins’ between them. Usually knowing the strengths and capabilities of different scripting languages and software, plus where they can be joined to feed one into the next, gives me the sort of quick and dirty answers I need.

    But Dick specifies it as Environ$, why the $? is it purely optional or does it have a modifying effect?

  6. Mike, your code using Wscript correctly identified where the “My Documents” folder on my desktop actually resides on my computer. I’m sure you knew it would! Thank you for that.

    I’ve done a couple minor one-off type spreadsheets that relied on nobody doing what I did to my home computer. That’s not optimal and was bound to backfire on me some day. Now I can fix the code.

    The other part I like about it is that I can actually read and follow the code. I know I could incorporate that into my projects without wondering why it worked.

  7. Omar:
    “I can actually read and follow the code..I know I could incorporate that into my projects without wondering why it worked.”

    You know…it’s funny you say that. I recently spent some time gathering some code examples for a class I’m giving and I realized that I often lean toward variations of code that I can read and understand. I’m sure that leaves me doing some things “inefficiently”. But I’m willing to trade some inefficiency for something I can read and explain to others.

    I remember Bill Jelen once told me that Aladin Akyurek (a poster on his site) creates the most amazing array formulas to solve most problems. He tells people that if they ever get a formula from Aladin, just copy and paste it into the cell. Don’t worry how it works…it will just work. I can, of course, appreciate the charm of that statement, but I know it would frustrate me on some level to have some formula I don’t fully understand working in my spreadsheet.

    I guess I feel the same way about code.

  8. Mike, my lesson is some code (found on the internet from a trustworthy source) that I’m using to add and remove file folders. This particular code won’t remove a folder with a hidden or system file in it. Which means most folders that have had a picture in it that has been viewed using Thumbnails. Since the purpose of these folders is to contain pictures, well you get the idea. I end up copying the list of folders that need removing to a DOS batch file and delete them that way.

    Since I don’t understand the code, I don’t know how to modify it, or whether it is even possible to modify it.

    I had no idea you could access Wscript from VBA. I will be looking into that possibility to do this task.

  9. I agree with Jon the only reliable way to get the system folders is with the API. Environ can certainly fail (as in not return an expected result) in some systems and WScript might be disabled (it’s also slow while the object is created).

    For readability use the conventionally named constants, eg
    Const CSIDL_PERSONAL = &H5 ‘ my documents
    (ignore any “amp;” that might creep in before the “H”)

  10. Thanks to Mike (Alexander) .. in the environment I’m working in we have roaming profiles and the my documents folder is set to a network folder, yours was the only method that actually picked up the right address so thanks a lot for posting it!

  11. To be sure, the code should probably look like the following (it’s missing an extra “\\” &

    WIthout the extra bit in there, your path will be returned as “C:\Documents & Settings\userMy Documents” or “C:\Users\userDocuments”

  12. his technique is not valid for any newer OS, XP and prior maybe, but Vista, Win7, Win8 the code fails since MS renamed My Documents to just Documents (nothing like MS to throw a wrench in the spokes of it’s own system and screw over developer’s in the process). The only reliable method is to use an API or WScript to get the path of any Special Folder. The other potential issue is that Environ values can be hacked, so it is possible for a user to manipulate your code, better once again with the API/WScript technique.

  13. & is just a posting glitch – just remove the “amp;” portion, so you get instead “If SHGetFolderPath(&H0, &H5, -1, &H0, sBuffer) = 0 Then”.

    What’s killing me is the next line – the bloody thing just won’t compile – instead I get a Type Mismatch centered on ‘StrPtr’ every time I try to compile.

  14. @Frothingslosh If you’re using 64 bit Office, StrPtr returns a LongPtr, not a Long. So

    should work.

  15. Actually, mine continues to error on StrPtr, despite the function already being declared a LongPtr. Trying to figure out why, but there isn’t a lot of solid documentation I’ve found yet on the interwebs.

    Also, don’t foget you need the PtrSafe in the Declare Function:

    Private Declare PtrSafe Function

  16. great post! But two errors:

    – plz use simple quotes (ascii 34), instead of your “smart” quotes (ascii 147 and 148) — they break the code.

    – you’re missing a backslash. Should be:
    Environ$(“USERPROFILE”) & “\My Documents”

    – Note, this code will not work if the location of a library has been changed. Your code will only return the DEFAULT location. Is there a way to get the changed value?

    cheers!

  17. Fixed. I think the API version that’s linked returns the correct path even if it’s changed.


Posting code? Use <pre> tags for VBA and <code> tags for inline.

Leave a Reply

Your email address will not be published.