15 Replies Latest reply on Jun 11, 2013 9:00 PM by Josh Brady

    SaveAs "CommonDialog" object does not exist in VBA7?

    Chris Manger

      I am in the process of updating our macros to work with VBA7 / SolidWorks 2013.   I have a custom property macro that has a "CommonDialog" object which allows the user to select where they want to save the file.   When I load this macro in SW2013 / VBA7, I get a message stating "Could not load some objects because they are not available on this machine."   I tried finding the object in the VBA7 controls, but it does not exist.

       

      Is there a new object that replaces the CommonDialog object?  If not, any suggestions on what I can use instead?

       

      Thanks.

        • Re: SaveAs "CommonDialog" object does not exist in VBA7?
          Jim Sculley

          CommonDialog was replaced by several distinct dialogs.  See:

           

          http://msdn.microsoft.com/en-us/library/256tssz7%28v=vs.90%29.aspx

           

          Jim S.

          • Re: SaveAs "CommonDialog" object does not exist in VBA7?
            Simon Turner

            In VBA7 you need to use Windows API calls. Paste the following into a module and use BrowseForFileSave or BrowseForFileOpen:

             

             

            Option Explicit

             

            Public Declare Function GetSaveFileName Lib "comdlg32.dll" Alias _

                        "GetSaveFileNameA" (pOpenfilename As OPENFILENAME) As Long

             

            Public Declare Function GetOpenFileName Lib "comdlg32.dll" Alias _

                        "GetOpenFileNameA" (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

             

            Public Type OPENFILENAME

                lStructSize As Long

                hwndOwner As Long

                hInstance As Long

                lpstrFilter As String

                lpstrCustomFilter As String

                nMaxCustFilter As Long

                nFilterIndex As Long

                lpstrFile As String

                nMaxFile As Long

                lpstrFileTitle As String

                nMaxFileTitle As Long

                lpstrInitialDir As String

                lpstrTitle As String

                flags As Long

                nFileOffset As Integer

                nFileExtension As Integer

                lpstrDefExt As String

                lCustData As Long

                lpfnHook As Long

                lpTemplateName As String

            End Type

             

             

            'OFS_FILE_OPEN_FLAGS and OFS_FILE_SAVE_FLAGS below

            'are mine to save long statements; they're not

            'a standard Win32 type.

            Public Const OFS_FILE_OPEN_FLAGS = OFN_EXPLORER Or _

                         OFN_LONGNAMES Or _

                         OFN_CREATEPROMPT Or _

                         OFN_NODEREFERENCELINKS

             

            Public Const OFS_FILE_SAVE_FLAGS = OFN_EXPLORER Or _

                         OFN_LONGNAMES Or _

                         OFN_OVERWRITEPROMPT Or _

                         OFN_HIDEREADONLY

             

             

            '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 BrowseForFileOpen(strTitle As String, myFilter As String, Optional initialDir As String = "") As String

                Dim i As Integer

                Dim OpenFile    As OPENFILENAME

                Dim lReturn     As Long

             

                OpenFile.lpstrFilter = myFilter

                OpenFile.nFilterIndex = 1

                OpenFile.hwndOwner = 0

                OpenFile.lpstrFile = String(257, 0)

                #If VBA7 Then

                    OpenFile.nMaxFile = LenB(OpenFile.lpstrFile) - 1

                    OpenFile.lStructSize = LenB(OpenFile)

                #Else

                    OpenFile.nMaxFile = Len(OpenFile.lpstrFile) - 1

                    OpenFile.lStructSize = Len(OpenFile)

                #End If

                OpenFile.lpstrFileTitle = OpenFile.lpstrFile

                OpenFile.nMaxFileTitle = OpenFile.nMaxFile

               

                OpenFile.lpstrInitialDir = initialDir

                OpenFile.lpstrTitle = strTitle

                OpenFile.flags = OFS_FILE_OPEN_FLAGS

                lReturn = GetOpenFileName(OpenFile)

             

                If lReturn = 0 Then

                    BrowseForFileOpen = ""

                Else

                    BrowseForFileOpen = Trim(Left(OpenFile.lpstrFile, InStr(1, OpenFile.lpstrFile, vbNullChar) - 1))

                End If

             

            End Function

             

            Public Function BrowseForFileSave(strTitle As String, myFilter As String, strInitialFile As String) As String

                Dim i As Integer

                Dim OpenFile    As OPENFILENAME

                Dim lReturn     As Long

                Dim mySaveFile As String

             

                OpenFile.lpstrFilter = myFilter

                OpenFile.nFilterIndex = 1

                OpenFile.hwndOwner = 0

                OpenFile.lpstrFile = String(257, 0)

                #If VBA7 Then

                    OpenFile.nMaxFile = LenB(OpenFile.lpstrFile) - 1

                    OpenFile.lStructSize = LenB(OpenFile)

                #Else

                    OpenFile.nMaxFile = Len(OpenFile.lpstrFile) - 1

                    OpenFile.lStructSize = Len(OpenFile)

                #End If

                OpenFile.lpstrFileTitle = OpenFile.lpstrFile

                OpenFile.nMaxFileTitle = OpenFile.nMaxFile

               

                If strInitialFile <> "" Then

                    i = InStrRev(strInitialFile, "\")

                    If i > 0 Then

                        OpenFile.lpstrInitialDir = Left(strInitialFile, i - 1)

                        mySaveFile = Mid(strInitialFile, i + 1)

                        OpenFile.lpstrFile = mySaveFile & String(257 - Len(mySaveFile), 0)

                    End If

                End If

             

                OpenFile.lpstrTitle = strTitle

                OpenFile.flags = OFS_FILE_SAVE_FLAGS

                lReturn = GetSaveFileName(OpenFile)

             

                If lReturn = 0 Then

                    BrowseForFileSave = ""

                Else

                    BrowseForFileSave = Trim(Left(OpenFile.lpstrFile, InStr(1, OpenFile.lpstrFile, vbNullChar) - 1))

                End If

             

            End Function

             

            Public Function OFNHookProc(ByVal hwnd As Long, _

                                        ByVal uMsg As Long, _

                                        ByVal wParam As Long, _

                                        ByVal lParam As Long) As Long

               Select Case uMsg

                  Case WM_INITDIALOG

                 

                  'Next line is not needed. Just left here as an example of how to hook the save dialog

                  'Call SendMessage(hwnd, BFFM_SETSELECTION, 1, ByVal initFile$)

                 

               End Select

               OFNHookProc = 0

            End Function

             

            Private Function GetAddress(ByVal Addr As Long) As Long

               GetAddress = Addr

            End Function

              • Re: SaveAs "CommonDialog" object does not exist in VBA7?
                Chris Manger

                Thanks for the post.

                 

                Do you have an example where this is used?   What are the strings that are passed?  Specifically strTitle and strInitialFile.

                 

                BrowseForFileSave(strTitle As String, myFilter As String, strInitialFile As String)

                  • Re: SaveAs "CommonDialog" object does not exist in VBA7?
                    Simon Turner

                    I think you should be able to get it working fairly easily.

                    strTitle is simply the text that appears in the banner of the window.

                    myFilter is the type of file you want to browse for. For example:

                    myFilter = "Text Files (*.txt)|*.txt"

                     

                    strInitialFIle can be left blank, but it is the default filename.

                      • Re: SaveAs "CommonDialog" object does not exist in VBA7?
                        Chris Manger

                        Thanks Simon.  I found your STL macro there.  https://forum.solidworks.com/message/362282#362282   I run into the same issue when copy/pasting your code above.   Stepping throught the macro, when it gets to this code:

                         

                            lReturn = GetSaveFileName(OpenFile)

                         

                            If lReturn = 0 Then

                                BrowseForFileSave = ""

                            Else

                                BrowseForFileSave = Trim(Left(OpenFile.lpstrFile, InStr(1, OpenFile.lpstrFile, vbNullChar) - 1))

                            End If

                         

                        It returns 0 which ends the macro.  I am trying to figure out what causes this.

                          • Re: SaveAs "CommonDialog" object does not exist in VBA7?
                            Simon Turner

                            OK - I noticed that it was missing the PtrSafe declaration on the API calls. Below is the updated code. To use it, here is an example snippet:

                             

                             

                                Dim myFileName As String

                               

                                myFileName = "test.txt"

                                myFileName = BrowseForFileOpen("Browse for a file", "Text Files (*.txt)" & vbNullChar & "*.txt", "")

                             

                            ------

                             

                            Option Explicit

                             

                            Public Declare PtrSafe Function GetSaveFileName Lib "comdlg32.dll" Alias _

                                        "GetSaveFileNameA" (pOpenfilename As OPENFILENAME) As Long

                             

                            Public Declare PtrSafe Function GetOpenFileName Lib "comdlg32.dll" Alias _

                                        "GetOpenFileNameA" (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

                             

                            Public Type OPENFILENAME

                                lStructSize As Long

                                hwndOwner As LongPtr

                                hInstance As LongPtr

                                lpstrFilter As String

                                lpstrCustomFilter As String

                                nMaxCustFilter As Long

                                nFilterIndex As Long

                                lpstrFile As String

                                nMaxFile As Long

                                lpstrFileTitle As String

                                nMaxFileTitle As Long

                                lpstrInitialDir As String

                                lpstrTitle As String

                                flags As Long

                                nFileOffset As Integer

                                nFileExtension As Integer

                                lpstrDefExt As String

                                lCustData As Long

                                lpfnHook As LongPtr

                                lpTemplateName As String

                            End Type

                             

                             

                            'OFS_FILE_OPEN_FLAGS and OFS_FILE_SAVE_FLAGS below

                            'are mine to save long statements; they're not

                            'a standard Win32 type.

                            Public Const OFS_FILE_OPEN_FLAGS = OFN_EXPLORER Or _

                                         OFN_LONGNAMES Or _

                                         OFN_CREATEPROMPT Or _

                                         OFN_NODEREFERENCELINKS

                             

                            Public Const OFS_FILE_SAVE_FLAGS = OFN_EXPLORER Or _

                                         OFN_LONGNAMES Or _

                                         OFN_OVERWRITEPROMPT Or _

                                         OFN_HIDEREADONLY

                             

                             

                            '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 BrowseForFileOpen(strTitle As String, myFilter As String, Optional initialDir As String = "") As String

                                Dim i As Integer

                                Dim OpenFile    As OPENFILENAME

                                Dim lReturn     As Long

                             

                                OpenFile.lpstrFilter = myFilter

                                OpenFile.nFilterIndex = 1

                                OpenFile.hwndOwner = 0

                                OpenFile.lpstrFile = String(257, 0)

                                #If VBA7 Then

                                    OpenFile.nMaxFile = LenB(OpenFile.lpstrFile) - 1

                                    OpenFile.lStructSize = LenB(OpenFile)

                                #Else

                                    OpenFile.nMaxFile = Len(OpenFile.lpstrFile) - 1

                                    OpenFile.lStructSize = Len(OpenFile)

                                #End If

                                OpenFile.lpstrFileTitle = OpenFile.lpstrFile

                                OpenFile.nMaxFileTitle = OpenFile.nMaxFile

                               

                                If initialDir <> "" Then OpenFile.lpstrInitialDir = Left(initialDir, i - 1)

                                OpenFile.lpstrTitle = strTitle

                                OpenFile.flags = OFS_FILE_OPEN_FLAGS

                                lReturn = GetOpenFileName(OpenFile)

                             

                                If lReturn = 0 Then

                                    BrowseForFileOpen = ""

                                Else

                                    BrowseForFileOpen = Trim(Left(OpenFile.lpstrFile, InStr(1, OpenFile.lpstrFile, vbNullChar) - 1))

                                End If

                             

                            End Function

                             

                            Public Function BrowseForFileSave(strTitle As String, myFilter As String, strInitialFile As String) As String

                                Dim i As Integer

                                Dim OpenFile    As OPENFILENAME

                                Dim lReturn     As Long

                                Dim mySaveFile As String

                             

                                OpenFile.lpstrFilter = myFilter

                                OpenFile.nFilterIndex = 1

                                OpenFile.hwndOwner = 0

                                OpenFile.lpstrFile = String(257, 0)

                                #If VBA7 Then

                                    OpenFile.nMaxFile = LenB(OpenFile.lpstrFile) - 1

                                    OpenFile.lStructSize = LenB(OpenFile)

                                #Else

                                    OpenFile.nMaxFile = Len(OpenFile.lpstrFile) - 1

                                    OpenFile.lStructSize = Len(OpenFile)

                                #End If

                                OpenFile.lpstrFileTitle = OpenFile.lpstrFile

                                OpenFile.nMaxFileTitle = OpenFile.nMaxFile

                               

                                If strInitialFile <> "" Then

                                    i = InStrRev(strInitialFile, "\")

                                    If i > 0 Then

                                        OpenFile.lpstrInitialDir = Left(strInitialFile, i - 1)

                                        mySaveFile = Mid(strInitialFile, i + 1)

                                        OpenFile.lpstrFile = mySaveFile & String(257 - Len(mySaveFile), 0)

                                    End If

                                End If

                             

                                OpenFile.lpstrTitle = strTitle

                                OpenFile.flags = OFS_FILE_SAVE_FLAGS

                                lReturn = GetSaveFileName(OpenFile)

                             

                                If lReturn = 0 Then

                                    BrowseForFileSave = ""

                                Else

                                    BrowseForFileSave = Trim(Left(OpenFile.lpstrFile, InStr(1, OpenFile.lpstrFile, vbNullChar) - 1))

                                End If

                             

                            End Function

                             

                            Public Function OFNHookProc(ByVal hwnd As Long, _

                                                        ByVal uMsg As Long, _

                                                        ByVal wParam As Long, _

                                                        ByVal lParam As Long) As Long

                               Select Case uMsg

                                  Case WM_INITDIALOG

                                 

                                  'Next line is not needed. Just left here as an example of how to hook the save dialog

                                  'Call SendMessage(hwnd, BFFM_SETSELECTION, 1, ByVal initFile$)

                                 

                               End Select

                               OFNHookProc = 0

                            End Function

                             

                            Private Function GetAddress(ByVal Addr As Long) As Long

                               GetAddress = Addr

                            End Function

                    • Re: SaveAs "CommonDialog" object does not exist in VBA7?
                      Keith Rice

                      Chris,

                       

                      Simon has given you a good start but if you want a more general overview of making your macros compatible with VBA7 then you might like to read this:

                       

                      How to make your VBA macros x64 compatible

                       

                      Keith

                      Video Tutorials for the SolidWorks API