27 Replies Latest reply on Oct 24, 2014 5:07 PM by Steve Soeder

    VBA select multiple files from file browser

    Steve Soeder

      I need to select multiple files to manipulate through a file browser dialog.

       

      I've explored the "GetOpenFileName" method, but this only allows you to select a single file.

       

      Does any one have an example of how I could do this?

       

      What I want to happen is:

      User selects files.

      Program opens each file, perfoms some action, closes file.

      Control returned to user.

          • Re: VBA select multiple files from file browser
            Steve Soeder

            Thank you Josh.

            The eng-tips link you provided points to two possible solutions.

            I tried the windows common dialog (first link) and after updating the code for 64 bit I was unable to get a working dialog - the "demo" routine crashes the application every time.  I dont have enough experience with these .dll functions to get into troubleshooting, so I will probably try something else.

             

            I may try the excel based example, however I dont particularly like the idea of having to call up another application to achieve this functionality.  I will continue searching, but thank you for the links, a great start.

             

            EDIT:  Marked as correct answer, however I still would like to find a better method if possible.

              • Re: VBA select multiple files from file browser
                Steve Soeder

                When using the excel multi select dialog, it seems to be working, but the dialog is opened behind the Solidworks application.

                The solidworks application is unresponsive while the dialog is opened, so I first thought the code had caused SW to hang as the window did not appear, and SW became unresponsive.

                When I checked in task manager, the dialog was open, and I was able to right-click and select "bring to front".

                 

                 

                The code below runs when a button is pressed on a user form.

                In the snippet below, the red line is the call to the file open dialog.  How can I force this window to open in front?

                 

                Dim j As Long
                Dim AlreadyInList As Boolean
                Dim swApp As SldWorks.SldWorks

                Set swApp = Application.SldWorks

                If Me.chkMultiSel Then 'Use Excel to select
                    Dim myXL As Excel.Application
                    Dim i As Long
                    Dim SaveDefaultPath As String
                    Dim PickedFiles As Variant
                 
                    Set myXL = New Excel.Application
                    SaveDefaultPath = myXL.DefaultFilePath  'memorize current default
                    myXL.DefaultFilePath = swApp.GetCurrentWorkingDirectory 'set new default
                    Set myXL = Nothing 'Close Excel to save this change
                    Set myXL = New Excel.Application  'Open Excel again
                   PickedFiles = myXL.GetOpenFileName(EXCELFILTERSTRING, , "Choose Files...", , True)
                    myXL.DefaultFilePath = SaveDefaultPath  'Set default path back like it was
                    Set myXL = Nothing   'Close Excel

                  • Re: VBA select multiple files from file browser
                    Steve Soeder

                    Well I'm not sure this is the cleanest way to do it, but I changed the items in green below and it now appears in front.
                    I still would like to know if there is a better way to do this, maybe using FileSystemObject, or something of the like.

                    I dont have a ton of time to play with it though.  We were upgrading EPDM database today, so I had some donwtime to do a little testing, but not sure when I'll have more time to play with it.

                     

                     

                        Dim myXL As Excel.Application

                        Dim i As Long

                        Dim SaveDefaultPath As String

                        Dim PickedFiles As Variant

                        Dim varTemp As Variant

                        Dim fdOpen As FileDialog

                       

                        ReDim PickedFiles(1 To 1)

                     

                        Set myXL = New Excel.Application

                        SaveDefaultPath = myXL.DefaultFilePath  'memorize current default

                        myXL.DefaultFilePath = swApp.GetCurrentWorkingDirectory 'set new default

                        Set myXL = Nothing 'Close Excel to save this change

                        Set myXL = New Excel.Application  'Open Excel again

                        Set fdOpen = myXL.FileDialog(msoFileDialogOpen)

                            With fdOpen

                                .AllowMultiSelect = True

                                .Show

                                    For Each varTemp In .SelectedItems

                                            If Not IsEmpty(PickedFiles(UBound(PickedFiles))) Then ReDim Preserve PickedFiles(1 To UBound(PickedFiles) + 1)

                                        PickedFiles(UBound(PickedFiles)) = varTemp

                                    Next

                            End With

                     

              • Re: VBA select multiple files from file browser
                Keith Rice

                Steve,

                 

                Maybe these are already covered in Josh's link, but here are my two suggestions:

                 

                1. Convert the macro to a VB.NET add-in or stand-alone. This is probably the wisest option, really, since .NET has much better options for dialog boxes. I realize, however, that due to time constraints it might not be a realistic option.

                 

                2. Create your own dialog box. Use the Dir() function to populate a listbox on a user form with all of the files in a folder that the user selects using a regular browse-for-folder dialog box. Then let the user select multiple items in the list box, and click Process (or whatever).

                 

                If you need a VBA7-compatible browse-for-folder dialog box then please email me. Let me also note that if you need to make any code compatible with VBA7, I have a guide at my web site.

                 

                Keith

                SolidWorks API Video Tutorials

                • Re: VBA select multiple files from file browser
                  Patrick Ford

                  Im sure this is an obvious question but I cannot get the answer. How do you call this function.

                  I want to execute a file dialog by clicking a command button on the user form.

                   

                  I've tried the simple:

                   

                  Sub CommandButton4_Click()

                   

                  Dim FileName As Variant

                  FileName = BrowseForFile()

                   

                  End Sub

                   

                  I know I'm just doing something wrong. Can anyone point me in the right direction?

                    • Re: VBA select multiple files from file browser
                      Steve Soeder

                      Patrick, the BrowseForFile function will return a string array.

                      See the documentation on GetOpenFileName here:

                      http://msdn.microsoft.com/en-us/library/windows/desktop/ms646927(v=vs.85).aspx

                      For information on the return and flags, see OpenFileName here:

                      http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839(v=vs.85).aspx

                      The important part for understaning the return is here:

                       

                      If the OFN_ALLOWMULTISELECT flag is set and the user selects multiple files, the buffer contains the current directory followed by the file names of the selected files. For Explorer-style dialog boxes, the directory and file name strings are NULL separated, with an extra NULL character after the last file name. For old-style dialog boxes, the strings are space separated and the function uses short file names for file names with spaces. You can use the FindFirstFile function to convert between long and short file names. If the user selects only one file, the lpstrFile string does not have a separator between the path and file name.

                       

                      So, what that means is the function is going to return a string that looks like this [Directory] &VbNullChar & [Filename1] & VbNullChar & [Filename 2] & VbNullChar  etc.

                       

                      So you should create a string varaible, and call the function to return that string, then you can use split to create an array of filenames.

                      I created a function for this, so I call this function from my procedure and get returned a string array of filenames. 

                       

                      Here is an example of the code I am using (I added commentes for you for what each line is doing):

                       

                      Private Function GetFiles() As String()
                          Dim strArray()          As String
                          Dim strReturn           As String
                          Dim strPath             As String
                          Dim lngX                As Long
                          Dim lngFirst            As Long
                          Dim lngLastExt          As Long
                          Dim lnglast             As Long
                         
                          ReDim strArray(0)
                          strReturn = BrowseForFile("Choose files...", "Solidworks drawings (*.slddrw)" & vbNullChar & "*.slddrw" & vbNullChar, "C:\TEST 1")
                          lngFirst = InStr(1, strReturn, vbNullChar) - 1 'find the location of the first filename
                          lngLastExt = InStrRev(strReturn, ".")  'find the location of the "." before the extension of the last filename
                          lnglast = InStr(lngLastExt, strReturn, vbNullChar) - 1  'find the end of the last filename extension
                          strPath = Trim(Left(strReturn, lngFirst)) & "\"  'extract the directory
                          strReturn = Trim(Left(strReturn, lnglast))  'trim the string to get rid of excess null characters at the end
                          strReturn = Trim(Mid(strReturn, lngFirst + 1))  'trim the string to get rid of directory and only include filenames
                              While InStr(1, strReturn, vbNullChar) = 1  'use a loop to delete excess null characters
                                  strReturn = Mid(strReturn, 2)
                              Wend
                        
                              strArray = Split(strReturn, vbNullChar)  'use split function to create an array containing each filename

                              For lngX = LBound(strArray) To UBound(strArray)  'add directory to each filename to create the full path
                                  strArray(lngX) = strPath & strArray(lngX)
                              Next
                          GetFiles = strArray  'return the array to the calling function

                      End Function

                       

                       

                      So, as an example of how to use this, here we have a userform with a list box.  When we click the "add" button, we get to select our files, and they are added to our listbox.

                       

                       

                      Private Sub btnAdd_Click()

                         

                          Dim lngX                As Long

                          Dim lngY                As Long

                          Dim blnExists           As Boolean

                          Dim swApp               As SldWorks.SldWorks

                          Dim strArrayFiles()     As String

                         

                         

                          Set swApp = Application.SldWorks

                          ReDim strArrayFiles(0)

                          strArrayFiles = GetFiles  'Calling our function which returns a string array with the long path for the files

                         

                              If IsArray(strArrayFiles) Then 'check that we selected files and returned an array

                                  For lngX = LBound(strArrayFiles) To UBound(strArrayFiles) 'check if file already is in list so we dont add it twice

                                      blnExists = False

                                      For lngY = 0 To Me.lstFileNames.ListCount - 1

                                          If UCase(strArrayFiles(lngX)) = UCase(Me.lstFileNames.List(lngY, 0)) Then 'if its in the list, we flag it as such

                                              blnExists = True

                                          End If

                                      Next lngY

                                      If Not blnExists Then

                                          Me.lstFileNames.AddItem strArrayFiles(lngX) 'if its not in the list already, add it

                                      End If

                                  Next lngX

                              End If

                      End Sub

                       

                       

                      I've attached my macro (for saving files as PDF) if you're intersted in disecting it further.  This was not created with distribution in mind, so you may need to edit things to make it work in your environment.  You could also do more to make it modular for plug-and play with more macros if you like, however I did not go that far with it.  There is some functionality I intended to add at a later date, as this was just a quick project while I had some time, which is not complete.  Feel free to edit it as you see fit.

                       

                       

                      P.S. Solidworks moderators - it would be nice if you could add some sort of CODE format that we could use.  Some forums even will display code (wrapped in tags) similar to what you see in the editor, so it shows the functions, variables, etc. highlighted in the same colors. 

                        • Re: VBA select multiple files from file browser
                          Patrick Ford

                          When I run the sub you gave me with the code you provided and the BrowseForFile function from above, I now get an internal error in the BrowseForFile Function at the 'Dim OpenFile     As OPENFILENAME' line. Are there any special references that I may be missing. I'm simply copying and pasting the code and making sure the Dim statements, etc. do not conflict. I cannot see what I am doing wrong.

                           

                          Message was edited by: Patrick Ford Steve, disregard the above part of this post. Your function didnt come in as Public. When I changed it to public it opened the dialog just fine. I still have to test for functionality. But thank you immensely

                            • Re: VBA select multiple files from file browser
                              Steve Soeder

                              What does the error say?

                              I dont believe any special references were required.

                              Have you tried running anything from the macro I uploaded?

                              Try opening that and try running the "SaveThemAll" procedure from the SaveAsPdf module and let me know if you get the same error.

                                • Re: VBA select multiple files from file browser
                                  Patrick Ford

                                  The dialog is opening correctly.

                                  When I select a file and click 'Open' I get a runtime Error '5'

                                  Invalid procedure call or argument

                                   

                                  You have helped me so much already I couldn't possibly expect you to help troubleshoot every little issue that I'm having...but if you have seen this and have a fix I'd appreciate the help. Thanks

                                   

                                  Message was edited by: Patrick Ford I'm opening the file you added earlier to see if it will run correctly

                                    • Re: VBA select multiple files from file browser
                                      Steve Soeder

                                      In the module "SavePdfs" at the very top is a constant declaration for the start path.

                                      This is to my local drive (its where I output the PDFs).
                                      Change this to your drive.

                                      See if that fixes it.

                                       

                                      Also, I just realized that was above the "Option Explicit" declaration.

                                      It wont affect functionality, but it would be good to move the "Option Explicit" to the top.

                                       

                                      See below:

                                      Option Explicit

                                      Const strMySavePath As String = "C:\Users\ssoeder\Documents\_temp\EPDM\STAGING\"

                                        • Re: VBA select multiple files from file browser
                                          Patrick Ford

                                          I had caught your local drive in there before I ran it.

                                          Unfortunately, I can't exactly say what I changed to get it to work - but I can say that IT WORKS!

                                          Steve, thank you so very much. I have been working on getting this to work for weeks.

                                          I think part of the problem for the runtime error was because, in testing, I was only selecting one file. For some reason the code doesn't like only one file being selected. I will have to search the code to verify if this is true.

                                          Thanks again. I will be posting my finished program soon.

                                            • Re: VBA select multiple files from file browser
                                              Steve Soeder

                                              Good catch!

                                              I guess I hadnt tried selecting a single file?

                                              Now, when I would select a single file, I did not get any error, but I did note that it was not being added to my list.

                                              Maybe in your calling procedure you get that error if an empty array is passed, or a zero-length string?

                                               

                                              The problem I found was with the string modifications I was making (to get rid of excess Null characters) prior to using the Split function.

                                              If only one file was returned, the trims I was using were trimming the string to nothing!

                                               

                                              I updated the funcion "GetFiles" , changes are highlighted in BLUE.

                                              Private Function GetFiles() As String()
                                                  Dim strArray()          As String
                                                  Dim strReturn           As String
                                                  Dim strPath             As String
                                                  Dim lngX                As Long
                                                  Dim lngFirst            As Long
                                                  Dim lngLastExt          As Long
                                                  Dim lnglast             As Long
                                                 
                                                  ReDim strArray(0)
                                                  strReturn = BrowseForFile("Choose files...", "Solidworks drawings (*.slddrw)" & vbNullChar & "*.slddrw" & vbNullChar, "C:\TEST 1")
                                                  lngFirst = InStrRev(strReturn, "\") - 1
                                                  lngLastExt = InStrRev(strReturn, ".")
                                                  lnglast = InStr(lngLastExt, strReturn, vbNullChar) - 1
                                                  strPath = Trim(Left(strReturn, lngFirst)) & "\"
                                                  strReturn = Trim(Left(strReturn, lnglast))
                                                  strReturn = Trim(Mid(strReturn, lngFirst + 1))
                                                      If Left(strReturn, 1) = "\" Then strReturn = Trim(Right(strReturn, Len(strReturn) - 1))
                                                      While InStr(1, strReturn, vbNullChar) = 1
                                                          strReturn = Mid(strReturn, 2)
                                                      Wend
                                                
                                                      strArray = Split(strReturn, vbNullChar)

                                                      For lngX = LBound(strArray) To UBound(strArray)
                                                          strArray(lngX) = strPath & strArray(lngX)
                                                      Next
                                                  GetFiles = strArray

                                              End Function

                                                • Re: VBA select multiple files from file browser
                                                  Patrick Ford

                                                  Just a heads up:

                                                  When you use

                                                   

                                                  lngFirst = InStrRev(strReturn, "\") - 1


                                                  in your GetFiles function you add the parent folder of whichever files you select to your list.

                                                  When omitted, the code works properly except for if the user cancels the file open dialog there is an error

                                                  starting at the line

                                                   

                                                  strPath = Trim(Left(strReturn, lngFirst)) & "\"

                                                   

                                                  in the GetFiles function. This is most likely due to some zero length issue. I haven't completely figured it out yet but thought I would share my findings. The error is present in your SaveAsPDF file.

                                                    • Re: VBA select multiple files from file browser
                                                      Steve Soeder

                                                      Not sure exactly what you mean about the parent folder being added to the list.

                                                      For me, the list populates exactly as I want, with a string for each file conatining the full path to that file.

                                                      I want the full path for each file because I need this in my calling procedure.
                                                      If you dont want the full path (you want just the file names) then remove the code highlighted in RED below.

                                                       

                                                      I believe you are correct, as written it probably would throw an error if you cancelled on the file select dialog.

                                                      I've added a check immediately after calling the BrowseForFile function to check that a file was selected.  If none is selcted, it will return an empty array, which you can then check in your calling procedure and handle as needed. 

                                                      I also cleaned up the trim function, so its not called multiple times unneccessarily.

                                                      Try the code below (not tested).

                                                       

                                                       

                                                       

                                                       

                                                      Private Function GetFiles() As String()
                                                          Dim strArray()          As String
                                                          Dim strReturn           As String
                                                          Dim strPath             As String
                                                          Dim lngX                As Long
                                                          Dim lngFirst            As Long
                                                          Dim lngLastExt          As Long
                                                          Dim lnglast             As Long
                                                         
                                                          ReDim strArray(0)
                                                          strReturn = BrowseForFile("Choose files...", "Solidworks drawings (*.slddrw)" & vbNullChar & "*.slddrw" & vbNullChar, "C:\TEST 1")
                                                             If Len(strReturn) > 1 Then
                                                                  lngFirst = InStrRev(strReturn, "\") - 1
                                                                  lngLastExt = InStrRev(strReturn, ".")
                                                                  lnglast = InStr(lngLastExt, strReturn, vbNullChar) - 1
                                                                  strPath = Left(strReturn, lngFirst) & "\"
                                                                  strReturn = Left(strReturn, lnglast)
                                                                  strReturn = Mid(strReturn, lngFirst + 1)
                                                                      If Left(strReturn, 1) = "\" Then strReturn = Right(strReturn, Len(strReturn) - 1)
                                                                  strReturn = Trim(strReturn)
                                                                      While InStr(1, strReturn, vbNullChar) = 1
                                                                          strReturn = Mid(strReturn, 2)
                                                                      Wend
                                                                
                                                                      strArray = Split(strReturn, vbNullChar)
                                                             
                                                                      For lngX = LBound(strArray) To UBound(strArray)
                                                                          strArray(lngX) = strPath & strArray(lngX)
                                                                      Next
                                                             End If
                                                          GetFiles = strArray

                                                      End Function

                                                        • Re: VBA select multiple files from file browser
                                                          Steve Soeder

                                                          Patrick, not sure how far along you got with your project.

                                                          I cleaned up some things today.

                                                          Updated macro is attached if you need it.

                                                            • Re: VBA select multiple files from file browser
                                                              Patrick Ford

                                                              Ok Steve,

                                                              Have you had any issues with only being able to select a few files at a time. I think the max for me is 15 parts. I can select more in the file dialog, however, only (15) will be added to my ListBox at a time. I can go back and select another 15 and all 30 will then populate into the list. If you've seen this or can pinpoint what part of the code is causing this please let me know

                                                                • Re: VBA select multiple files from file browser
                                                                  Steve Soeder

                                                                  Patrick, my best guess is that you are returning a string with approximately 32K or more characters.

                                                                  The GetOpenFilenameA API function returns an ANSI formatted string limited to 32k characters.

                                                                   

                                                                  If you ned to be able to select more files, you may want to look at GetOpenFilenameW, which returns a Unicode string, which can be of unlimited length.

                                                                   

                                                                  VBA does handle unicode strings, however it does funny things with external strings coming in and converting between unicode/ansi without telling you.  I'm not sure what all you would have to change to get it to work with the GetOpenFilenameW version. You may need to look at using pointers instead of string variables, and I dont know what else you'll need to do to get it working correctly. 

                                                                   

                                                                  If you do any work on it, please share your progress.

                                                                   

                                                                  EDIT:  Check out this link I found, it might point you in the right direction.

                                                                  http://blog.nkadesign.com/2013/vba-unicode-strings-and-the-windows-api/

                                                                    • Re: VBA select multiple files from file browser
                                                                      Steve Soeder

                                                                      Patrick,  not sure where you ended up with this.

                                                                      Here is a version I put together that uses the GetOpenFileNameW call.

                                                                      See if this works for you

                                                                       

                                                                       

                                                                      Option Explicit
                                                                      '***NOTE: _
                                                                          This class object requires the following references: _
                                                                              <NONE>
                                                                      
                                                                      'Declare the windows API function for GetOpenFileNameA
                                                                      'MSDN Reference: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646927(v=vs.85).aspx
                                                                      Public Declare PtrSafe Function GetOpenFileNameU Lib "comdlg32.dll" Alias "GetOpenFileNameW" (pOpenfilename As OPENFILENAME) As Long
                                                                      
                                                                      Public Const OFN_ALLOWMULTISELECT As Long = &H200
                                                                      Public Const OFN_CREATEPROMPT As Long = &H2000
                                                                      Public Const OFN_ENABLEHOOK As Long = &H20
                                                                      Public Const OFN_ENABLETEMPLATE As Long = &H40
                                                                      Public Const OFN_ENABLETEMPLATEHANDLE As Long = &H80
                                                                      Public Const OFN_EXPLORER As Long = &H80000
                                                                      Public Const OFN_EXTENSIONDIFFERENT As Long = &H400
                                                                      Public Const OFN_FILEMUSTEXIST As Long = &H1000
                                                                      Public Const OFN_HIDEREADONLY As Long = &H4
                                                                      Public Const OFN_LONGNAMES As Long = &H200000
                                                                      Public Const OFN_NOCHANGEDIR As Long = &H8
                                                                      Public Const OFN_NODEREFERENCELINKS As Long = &H100000
                                                                      Public Const OFN_NOLONGNAMES As Long = &H40000
                                                                      Public Const OFN_NONETWORKBUTTON As Long = &H20000
                                                                      Public Const OFN_NOREADONLYRETURN As Long = &H8000& '*see comments
                                                                      Public Const OFN_NOTESTFILECREATE As Long = &H10000
                                                                      Public Const OFN_NOVALIDATE As Long = &H100
                                                                      Public Const OFN_OVERWRITEPROMPT As Long = &H2
                                                                      Public Const OFN_PATHMUSTEXIST As Long = &H800
                                                                      Public Const OFN_READONLY As Long = &H1
                                                                      Public Const OFN_SHAREAWARE As Long = &H4000
                                                                      Public Const OFN_SHAREFALLTHROUGH As Long = 2
                                                                      Public Const OFN_SHAREWARN As Long = 0
                                                                      Public Const OFN_SHARENOWARN As Long = 1
                                                                      Public Const OFN_SHOWHELP As Long = &H10
                                                                      Public Const OFN_ENABLESIZING As Long = &H800000
                                                                      Public Const OFS_MAXPATHNAME As Long = 260
                                                                      'Create a custom type that matches the OPENFILENAME structure
                                                                      'MSDN reference: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839(v=vs.85).aspx
                                                                      Public Type OPENFILENAME
                                                                          lStructSize As Long
                                                                          hwndOwner As LongPtr
                                                                          hInstance As LongPtr
                                                                          lpstrFilter As LongPtr
                                                                          lpstrCustomFilter As LongPtr
                                                                          nMaxCustFilter As Long
                                                                          nFilterIndex As Long
                                                                          lpstrFile As LongPtr
                                                                          nMaxFile As Long
                                                                          lpstrFileTitle As LongPtr
                                                                          nMaxFileTitle As Long
                                                                          lpstrInitialDir As LongPtr
                                                                          lpstrTitle As LongPtr
                                                                          flags As Long
                                                                          nFileOffset As Integer
                                                                          nFileExtension As Integer
                                                                          lpstrDefExt As LongPtr
                                                                          lCustData As Long
                                                                          lpfnHook As LongPtr
                                                                          lpTemplateName As LongPtr
                                                                      End Type
                                                                      'OFS_FILE_OPEN_FLAGS:
                                                                      'Can view explanation of flags here on the MSDN reference: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839(v=vs.85).aspx
                                                                      Public Const OFS_FILE_OPEN_FLAGS = _
                                                                                      OFN_EXPLORER Or _
                                                                                      OFN_LONGNAMES Or _
                                                                                      OFN_CREATEPROMPT Or _
                                                                                      OFN_NODEREFERENCELINKS
                                                                                   
                                                                      'Windows version constants
                                                                      Private Const VER_PLATFORM_WIN32_NT As Long = 2
                                                                      Private Const OSV_LENGTH As Long = 76
                                                                      Private Const OSVEX_LENGTH As Long = 88
                                                                      Public OSV_VERSION_LENGTH As Long
                                                                      Public Const WM_INITDIALOG As Long = &H110
                                                                      Private Const SW_SHOWNORMAL As Long = 1
                                                                      Public Function BrowseForFile(strTitle As String, myFilter As String, Optional initialDir As String = "") As String
                                                                      'This function allows you to browse for files and returns a string containing the files selected
                                                                      'Declare variables
                                                                          Dim OpenFile    As OPENFILENAME
                                                                          Dim lReturn     As Long
                                                                          Dim strFile     As String
                                                                      'Set the file type filter
                                                                          OpenFile.lpstrFilter = StrPtr(myFilter)
                                                                          
                                                                      'Set the filter index.  This is the order of the filters available to select from in the dialog.  1= the first in the list (and currently active)
                                                                          OpenFile.nFilterIndex = 1
                                                                      'Set the handle to the window that owns the dialog box
                                                                          OpenFile.hwndOwner = 0
                                                                      'lpstrFile is a pointer to a string which contains the current directory followed by list of file names selected. _
                                                                      'Create an empty string to use as buffer, it needs to be at least 256 chars plus a terminating NULL char
                                                                          strFile = String(257, 0)
                                                                      'Pass the buffer string to the pointer
                                                                          OpenFile.lpstrFile = StrPtr(strFile)
                                                                          
                                                                      'The size of nMaxFile = the size, in characters, of the string pointed to by lpstrFile (less one NULL character at the end)
                                                                      'The size of lStructSize = The length, in bytes, of the structure. Use size of (OPENFILENAME) for this parameter.
                                                                          
                                                                      'BEFORE we can set the above two properties, we need to heck which version of VBA we are working with (SW uses VBA7, Office uses VBA6) _
                                                                       The # indiicates preprocessor command, which is processed prior to compilation, which ensures that the code compiles per the correct platform
                                                                              #If VBA7 Then
                                                                              'When environment is VBA7, use LenB (binary compare)
                                                                                  OpenFile.nMaxFile = LenB(strFile) - 1
                                                                                  OpenFile.lStructSize = LenB(OpenFile)
                                                                              #Else
                                                                              'When environment is anything else, use Len (text compare)
                                                                                  OpenFile.nMaxFile = Len(strFile) - 1
                                                                                  OpenFile.lStructSize = Len(OpenFile)
                                                                              #End If
                                                                      'This points to a string containing just the file name and extension (without path info), whereas lpstrFile contains the path info also.
                                                                          OpenFile.lpstrFileTitle = OpenFile.lpstrFile
                                                                      'This is to lpstrFileTile what nMaxFile is to lpstrFile
                                                                          OpenFile.nMaxFileTitle = OpenFile.nMaxFile
                                                                          'Check if the calling procedure specified a starting directory
                                                                              If initialDir <> "" Then OpenFile.lpstrInitialDir = StrPtr(StrConv(initialDir, vbUnicode))
                                                                      'This will be the title of the window dialog, and is an argument that must be passed by the calling procedure
                                                                          OpenFile.lpstrTitle = StrPtr(StrConv(strTitle, vbUnicode))
                                                                      'Flags control how the window looks and acts. _
                                                                      'Can view explanation of flags here on the MSDN reference: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839(v=vs.85).aspx
                                                                          OpenFile.flags = OFS_FILE_OPEN_FLAGS + OFN_ALLOWMULTISELECT
                                                                      'Call the windows API function we delcared and get the return when it completes.
                                                                          lReturn = GetOpenFileNameU(OpenFile)
                                                                          
                                                                      'Check the return, if 0 then no files selected or user cancelled
                                                                          If lReturn = 0 Then
                                                                              BrowseForFile = ""
                                                                          Else
                                                                          'lpstrFile contains the current directory followed by list of file names
                                                                              BrowseForFile = strFile
                                                                          End If
                                                                      End Function
                                                                      Public Function GetFiles() As String()
                                                                      'This function wraps the BrowseForFiles function above for use in our program.  It returns a string array of fully qualified filenames.
                                                                          
                                                                      'Declare variables
                                                                          Dim strArray()          As String
                                                                          Dim strReturn           As String
                                                                          Dim strPath             As String
                                                                          Dim lngX                As Long
                                                                          Dim lngFirst            As Long
                                                                          Dim lngLastExt          As Long
                                                                          Dim lnglast             As Long
                                                                          Dim lngBS               As Long
                                                                          
                                                                      'Initialize the array
                                                                          ReDim strArray(0)
                                                                      'Call the BrowseForFile function and get the files returned
                                                                          strReturn = BrowseForFile("Choose files...", "Solidworks drawings (*.slddrw)" & vbNullChar & "*.slddrw" & vbNullChar, "C:\TEST 1")
                                                                              
                                                                              'Check that we got a proper return which will have the full directory address and filenames
                                                                                  lngBS = InStrRev(strReturn, "\") - 1
                                                                                      If lngBS = -1 Then Exit Function
                                                                              
                                                                              'Find the starting position for the first filename
                                                                                  lngFirst = InStr(lngBS, strReturn, vbNullChar) - 1
                                                                              'Find the position for start of the file extension of the last filename
                                                                                  lngLastExt = InStrRev(strReturn, ".")
                                                                              'Find the position for the end of the last file name including the extension
                                                                                  lnglast = InStr(lngLastExt, strReturn, vbNullChar) - 1
                                                                              
                                                                              'Trim out all trailing NULL characters from the string
                                                                                  strReturn = Left(strReturn, lnglast)
                                                                              
                                                                                  'Get the path for directory the files were selected in, and remove it from the return string
                                                                                      If lngFirst = lnglast Then 'single file selected
                                                                                          strPath = Left(strReturn, lngBS) & "\"
                                                                                          strReturn = Mid(strReturn, lngBS + 2)
                                                                                      Else 'multiple files selected
                                                                                          strPath = Left(strReturn, lngFirst) & "\"
                                                                                          strReturn = Mid(strReturn, lngFirst + 1)
                                                                                      End If
                                                                                  
                                                                                  'Get rid of any "\" left at the start of the return string so we just have filenames
                                                                                      If Left(strReturn, 1) = "\" Then strReturn = Right(strReturn, Len(strReturn) - 1)
                                                                                  
                                                                              'Trim any leading/trailing spaces out of the return string
                                                                                  strReturn = Trim(strReturn)
                                                                              
                                                                                  'Get rid of any extra leading NULL characters
                                                                                      While InStr(1, strReturn, vbNullChar) = 1
                                                                                          strReturn = Mid(strReturn, 2)
                                                                                      Wend
                                                                                 
                                                                                 'Files are seperated by NULL characters, so we can create an array of the filenames by splitting on NULL characters
                                                                                      strArray = Split(strReturn, vbNullChar)
                                                                              
                                                                                  'Now loop through the array and add the path to each filename so it is fully qualified
                                                                                      For lngX = LBound(strArray) To UBound(strArray)
                                                                                          strArray(lngX) = strPath & strArray(lngX)
                                                                                      Next
                                                                              'End If
                                                                              
                                                                      'Return the array of fully qualified filenames to the calling procedure
                                                                          GetFiles = strArray
                                                                      End Function