By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,647 Members | 1,832 Online
Bytes IT Community
Submit an Article
Got Smarts?
Share your bits of IT knowledge by writing an article on Bytes.

Select a File or Folder using the FileDialog Object

NeoPa
Expert Mod 15k+
P: 31,260
Overview

It is often required to prompt the operator of an Access project to select a file or folder. Sure, it's possible to allow them to type it in freehand, or even paste it in from another application, but generally operators are more comfortable with the facility to select it from the existing file structure as they would in most Windows applications (with a file/folder selectioon window).

This is perfectly possible to do in Access (and any MS Office application of course, but we'll deal with Access here for simplicity). The details of what to do and how to do it can be found below. Attached to this post you can find an example database to play with which includes all this already implemented. There is also an associated video at VBA Tip: Select File or Folder using FileDialog in Access (cc) .


Objects

A single object is necessary. To implement this facility you use the FileDialog object from the MS Office Object library. This requires that the library is included as a reference of the project. If you don't find it already selected in the Tools \ References list (in the VBA IDE or Code Editor window) then select it using that same command. Versions differ, but the full name will probably look similar to "Microsoft Office XX.X Object Library". You may have to scroll down a long way to find it but most of the items in the list are arranged alphabetically.


File or Folder

Selecting files and selecting folders are very similar, but I'll cover the difference here just to be clear.

When selecting a file the operator can choose a folder either way (from the Look in: drop-down or the main section where files/folders within current folder are listed) and it will continue navigating into that folder. It will only return a value when a file is selected.

When selecting a folder however, it is still possible to navigate the folder structure using the Look in: drop-down, and even by double-clicking on a folder from the main section. To return the folder to the calling code, it is necessary to activate the OK button with a particular folder selected from the main section.


Example Database

To illustrate the usage of this I will knock up a simple database with a form containing two controls for selecting :
  1. A folder.
  2. A file.

As I don't want to do anything to anyone's files, the payload will simply be to display the full path of the folder or file in the associated label by the Command Button.

Structure and Objects of Example Database
There is very little to this in truth (See picture below for what it looks like).
  1. A form called frmFileDialog which has on it, apart from a title Label, an Exit button and its associated Label, two Command Buttons called cmdFolder and cmdFile, and an associated label for each (lblFolder and lblFile).
  2. The module associated with the form which contains the VBA code supporting the various controls.
  3. Another module, modMain, which simply contains the code for FSBrowse().




VBA Code

Let's start with a routine that provides a simple interface for using this object. I've called it FSBrowse and it's a function procedure.

Expand|Select|Wrap|Line Numbers
  1. Option Compare Database
  2. Option Explicit
  3.  
  4. 'FSBrowse (File System Browse) allows the operator to browse for a file/folder.
  5. '  strStart specifies where the process should start the browser.
  6. '  lngType specifies the MsoFileDialogType to use.
  7. '  strPattern specifies which FileType(s) should be included.
  8. Public Function FSBrowse(Optional strStart As String = "", _
  9.                          Optional lngType As MsoFileDialogType = _
  10.                              msoFileDialogFolderPicker, _
  11.                          Optional strPattern As String = "All Files,*.*" _
  12.                          ) As String
  13.     Dim varEntry As Variant
  14.  
  15.     FSBrowse = ""
  16.     With Application.FileDialog(dialogType:=lngType)
  17.         'Set the title to match the type used from the list
  18.         .Title = "Browse for "
  19.         Select Case lngType
  20.         Case msoFileDialogOpen
  21.             .Title = .Title & "File to open"
  22.         Case msoFileDialogSaveAs
  23.             .Title = .Title & "File to SaveAs"
  24.         Case msoFileDialogFilePicker
  25.             .Title = .Title & "File"
  26.         Case msoFileDialogFolderPicker
  27.             .Title = .Title & "Folder"
  28.         End Select
  29.         If lngType <> msoFileDialogFolderPicker Then
  30.             'Reset then add filter patterns separated by tildes (~) where
  31.             '  multiple extensions are separated by semi-colons (;) and the 
  32.             '  description is separated from them by a comma (,).
  33.             '  Example strPattern :
  34.             '  "MS Access,*.ACCDB; *.MDB~MS Excel,*.XLSX; *.XLSM; *.XLS"
  35.             Call .Filters.Clear
  36.             For Each varEntry In Split(strPattern, "~")
  37.                 Call .Filters.Add(Description:=Split(varEntry, ",")(0), _
  38.                                   Extensions:=Split(varEntry, ",")(1))
  39.             Next varEntry
  40.         End If
  41.         'Set some default settings
  42.         .InitialFileName = strStart
  43.         .AllowMultiSelect = False
  44.         .InitialView = msoFileDialogViewDetails
  45.         'Only return a value from the FileDialog if not cancelled.
  46.         If .Show Then FSBrowse = .SelectedItems(1)
  47.     End With
  48. End Function
This routine allows a fairly simple interface and returns the selected item if any is selected, but an empty string otherwise. It also has the benefit of illustrating some of the properties of this object that are typically used.

Next is the code behind the form which calls the function above. Very little to explain as the complexity level is so basic, but I'll include a few pointers below the code anyway.

Expand|Select|Wrap|Line Numbers
  1. Option Compare Database
  2. Option Explicit
  3.  
  4. Private Sub Form_Open(Cancel As Integer)
  5.     Call DoCmd.Restore
  6.     With Me
  7.         .lblFolder.Caption = Replace(CurrentProject.Path & "\", "\\", "\")
  8.         .lblFile.Caption = CurrentProject.FullName
  9.     End With
  10. End Sub
  11.  
  12. Private Sub cmdFolder_Click()
  13.     Dim strPath As String
  14.  
  15.     With Me
  16.         strPath = FSBrowse(strStart:=.lblFolder.Caption, _
  17.                            lngType:=msoFileDialogFolderPicker)
  18.         If strPath > "" Then _
  19.             .lblFolder.Caption = Replace(strPath & "\", "\\", "\")
  20.     End With
  21. End Sub
  22.  
  23. Private Sub cmdFile_Click()
  24.     Dim strPath As String
  25.  
  26.     With Me
  27.         strPath = Left(.lblFile.Caption, InStrRev(.lblFile.Caption, "\"))
  28.         strPath = FSBrowse(strStart:=strPath, _
  29.                            lngType:=msoFileDialogFilePicker, _
  30.                            strPattern:="MS Access Databases,*.ACCDB; *.MDB~" & _
  31.                                        "All Files,*.*")
  32.         If strPath > "" Then .lblFile.Caption = strPath
  33.     End With
  34. End Sub
  35.  
  36. Private Sub cmdExit_Click()
  37.     Call DoCmd.Close
  38. End Sub
  • Lines #4 - #10 Form_Open()
    This restores the form (in case it's either maximised or minimised).
    It also sets up the starting values of the labels that display both the folder (Line #7) and the file (Line #8). These values match, respectively, the folder and full name values for the current projuect. IE. The open database called
    Notice that it is only necessary to use Replace() for the folder as folder addresses can be returned either with or without a trailing slash (/) character. This code ensures one is added if, and only if, none is there already.
  • Lines #12 - #21 cmdFolder_Click()
    Lines #13 - #15 and #20 - #21 simply set up the code structure and don't actually do anything specific.
    Lines #16 - 17 call the FSBrowse function shown above. The strStart parameter tells it where to start browsing from. In this case it is the same as originally set up in Form_Open() or the value last returned if it has been run before. The lngType parameter tells it to look for a folder.
    Lines #18 - #19 simply save the returned value in the Caption of the label if if the FileDialog wasn't cancelled. Notice it also adds a back-slash (\) at the end, but only if there is not one there already.
  • Lines #23 - #34 cmdFile_Click()
    Lines #23 - #26 and #33 - #34 simply set up the code structure and don't actually do anything specific.
    Line #27 sets up the starting address. It ensures that the file name part is dropped otherwise the visible files are filtered to match only that name. Essentially it sets the value to match the folder part only of the last returned value from the label's Caption.
    Lines #28 - 31 call the FSBrowse function shown above. The strStart parameter tells it where to start browsing from. In this case it is set by line #27. The lngType parameter tells it to look for a file. The strPattern parameter specifies which filters to make available for use.
  • Lines #36 - #38 cmdExit_Click()
    Line #37 simply closes the current object which is the form.

Conclusion

This is actually a very easy thing to accomplish and to incorporate into any of your databases. Once the basics are understood there's no reason why it shouldn't be used anywhere and everywhere such a facility is called for.
Attached Images
File Type: jpg FileDialog.jpg (26.0 KB, 43807 views)
Attached Files
File Type: zip FileDialog.Zip (105.6 KB, 6947 views)
Aug 26 '11 #1
Share this Article
Share on Google+
11 Comments


P: 2
Hello NeoPa,

Thanks for your example!

There is one problem though: the .Filters.Add function throws error 438 (property or method not supported). For browsing a Folder I can bypass that, but not for selecting a file...

I have tried your mdb on both Access 2003 and Access 2010: both respond the same. Of course, I did set the right reference...
Mar 25 '13 #2

zmbd
Expert Mod 5K+
P: 5,287
Neo,
V4Friend is correct:

When the dialog is set to 'msoFileDialogFolderPicker"
Expand|Select|Wrap|Line Numbers
  1. For Each varEntry In Split(strPattern, "~")
  2.     Call .Filters.Add(Description:=Split(varEntry, ",") _
  3.        (0), Extensions:=Split(varEntry, ",")(1))
  4. Next varEntry
Will give the "unsupported" error.

When the function is used with the remaining file selection types, the code runs as intended...

Two options, Trap for error 438 and recover from the error (more than likely what I would do) or if we alter 33 to 37 in the first code block to something like:
Expand|Select|Wrap|Line Numbers
  1. <...>
  2. '>[Z{Used a select case here as I dislike the IF then for multiple true cases.}]
  3.         Select Case lngType
  4.         Case msoFileDialogOpen, msoFileDialogSaveAs, msoFileDialogFilePicker
  5.             Call .Filters.Clear
  6.             For Each varEntry In Split(strPattern, "~")
  7.                 Call .Filters.Add(Description:=Split(varEntry, ",")(0), _
  8.                               Extensions:=Split(varEntry, ",")(1))
  9.             Next varEntry
  10.         End Select
  11. <...>
We can avoid the nasty error all togeither, which was what I was taught to do.
Mar 25 '13 #3

P: 2
Hi zmbd,

Thanks. That's my opinion too: if you know an error is going to be thrown, try to prevent that.

It's working now. But I think it would have been better, if the FileDialog would just ignore a filter, instead of throwing an error. If one uses Intellisense, there is no telling it will fail in some cases...
Mar 26 '13 #4

NeoPa
Expert Mod 15k+
P: 31,260
I need to look into this.

I've been away on a heavy project recently and have a lot to catch up with, but it sounds like you've done well to bring this to my attention. I appreciate that :-)
Mar 26 '13 #5

P: 1
Thank you sooooo much for the simple code! :-)
I like that the browse has a starting point. There's only 1 issue I'm having. Although the correct folder is highlighted in the browse window, only the last 13 characters of the folder name are appearing in the "Folder name" box. If the user clicks OK, an error is displayed indicating "Path does not exist."
Granted, these test folder names are very long (the final folder names used will most likely be shorter) and the user is only going to browse if they want to change the folder anyway....
I just wanted to understand how this works and remove the chance of the user getting an error message.

Example:
folder name: QRY4 EXCEL FILE GOES HERE
folder name text box displays: FILE GOES HERE

Thanks!

Peace.....
May 16 '13 #6

NeoPa
Expert Mod 15k+
P: 31,260
This took a while to look at. Sorry.

It isn't appropriate to specify a filter when selecting a folder. I've updated the code in the OP to set filters in the routine only when :
Expand|Select|Wrap|Line Numbers
  1. lngType <> msoFileDialogFolderPicker
I believe this should resolve the issue. Thanks for the comments.
Feb 9 '14 #7

NeoPa
Expert Mod 15k+
P: 31,260
KSBAccess. Sorry to take so long to respond.

We don't generally answer questions IN an article. They are done in separate threads. In this case though you may find that enlarging your label controls will show more of the information that you currently are getting cropped. You're simply seeing the last line of data. If this doesn't resolve your issue then please do not respond in here, but post a new thread with your question.
Feb 9 '14 #8

NeoPa
Expert Mod 15k+
P: 31,260
I just updated the OP to include a link to the video I posted that accompanies this article (VBA Tip: Select File or Folder using FileDialog in Access (cc) ).
Oct 5 '14 #9

P: 2
Maybe it's me, but this generates this same error with the msoFileDialogSaveAs type too.
Mar 18 '15 #10

NeoPa
Expert Mod 15k+
P: 31,260
It's not just you Jerry :-(

I've had to use it in anger recently and was disappointed to find that trying to use it to specify the name of a file to save to meant going without the ability to specify the type.

I see no logical reason for that but it's there all the same.
Mar 19 '15 #11

P: 2
I've somewhat given up on it for the time being - it's damn near impossible to export a filtered query to excel too so it doesn't even matter where they put it :-)
Mar 20 '15 #12