2

I'm coding macros in vba Word and on visio 2013. I wanted to open a fileDialog so that the user can choose where to save his file.

I succeded in word, but in visio it doesn't to work the same.

I wrote this in word:

Dim dlg As FileDialog
Dim strPath As String

'Boite de dialogue pour choisir où enregistrer son fichier
Set dlg = Application.FileDialog(msoFileDialogFolderPicker)

With dlg
    .InitialFileName = Application.ActiveDocument.Path
    .AllowMultiSelect = False
    .Title = "Choisir le répertoire d'enregistrement"
    .Show
End With

strPath = dlg.SelectedItems(1)

but it doesn't work in visio. Can someone help me do the same in visio?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
user3314570
  • 237
  • 4
  • 14

2 Answers2

3

Although it says that Visio has Application.FileDialog, it will fail in Visio VBA.

However as a workaround, you can access the FileDialog object through Excel, Word or other Office applications. The code below does it using Word as you are using both.

This is a function that will return an array containing all the path from the selected files :

Public Function Get_File_via_FileDialog() As Variant
    'fd will be a FileDialog object
    Dim fd As Object
    'Array of pathes
    Dim A()
    ReDim A(0)

    'Create an Word object. You can access the FileDialog object through it.
    Dim WordApp As Object
    On Error Resume Next
    Set WordApp = GetObject(, "Word.Application")
    If Err.Number > 0 Then Set WordApp = CreateObject("Word.Application")
    On Error GoTo 0

    WordApp.Visible = True   'This statement necessary so you can see the FileDialog.

    'Declare a variable to contain the path
    'of each selected item. Even though the path is aString,
    'the variable must be a Variant because For Each...Next
    'routines only work with Variants and Objects.
    Dim vrtSelectedItem As Variant

    'Create a FileDialog object as a File Picker dialog box.
    Set fd = WordApp.FileDialog(msoFileDialogFilePicker)

    'Use a With...End With block to reference the FileDialog object.
    With fd
            'Use the Show method to display the File Picker dialog box and return the user's action.
            'The user pressed the button.
        If .Show = -1 Then
            WordApp.Visible = False  'Hide the Excel application

                'Step through each string in the FileDialogSelectedItems collection.
                For Each vrtSelectedItem In .SelectedItems

                    'vrtSelectedItem is a string that contains the path of each selected item.
                    'You can use any file I/O functions that you want to work with this path.
                    'This example displays the path in a message box.
                    A(UBound(A)) = vrtSelectedItem
                    ReDim Preserve A(UBound(A) + 1)
                Next vrtSelectedItem
            'The user pressed Cancel.
        End If
    End With

    'Set the object variable to nothing.
    ReDim Preserve A(UBound(A) - 1)

    Set fd = Nothing
    Set xl = Nothing
Get_File_via_FileDialog = A
End Function
R3uK
  • 14,417
  • 7
  • 43
  • 77
3

If you don't want to use other office application, you can use winapi OpenFileDialog to achieve similar behavior, but it won't as easy as with .FileDialog.

See more details here: Open File Dialog in Visio

The module source code (compatible with Visio 2010 and above, i.e. with editions which have x64 version). For the original source code, compatible with previous versions, chech the above link.

'// This is code that uses the Windows API to invoke the Open File
'// common dialog. It is used by users to choose a file

Private Declare PtrSafe Function GetOpenFileName Lib "comdlg32.dll" _
Alias "GetOpenFileNameA" (OFN As OPENFILENAME) As Boolean

Private 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

Public Sub OpenFile(ByRef filePath As String, _
                         ByRef cancelled As Boolean)

    Dim OpenFile As OPENFILENAME
    Dim lReturn As Long
    Dim sFilter As String

    ' On Error GoTo errTrap

    OpenFile.lStructSize = LenB(OpenFile)

    '// Sample filter:
    '// "Text Files (*.txt)" & Chr$(0) & "*.sky" & Chr$(0) & "All Files (*.*)" & Chr$(0) & "*.*"
    sFilter = "All Files (*.*)" & Chr(0) & "*.*"

    OpenFile.lpstrFilter = sFilter
    OpenFile.nFilterIndex = 1
    OpenFile.lpstrFile = String(257, 0)
    OpenFile.nMaxFile = Len(OpenFile.lpstrFile) - 1
    OpenFile.lpstrFileTitle = OpenFile.lpstrFile
    OpenFile.nMaxFileTitle = OpenFile.nMaxFile
    OpenFile.lpstrInitialDir = ThisDocument.Path

    OpenFile.lpstrTitle = "Find Excel Data Source"
    OpenFile.flags = 0
    lReturn = GetOpenFileName(OpenFile)

    If lReturn = 0 Then
       cancelled = True
       filePath = vbNullString
    Else
      cancelled = False
      filePath = Trim(OpenFile.lpstrFile)
      filePath = Replace(filePath, Chr(0), vbNullString)
    End If

    Exit Sub

errTrap:
    Exit Sub
    Resume

End Sub
Nikolay
  • 10,752
  • 2
  • 23
  • 51
  • Seems interesting but can you add the code (at least the basics)? Because this might be flagged as *low quality* as it is a *link only answer*! ;) – R3uK Nov 19 '15 at 13:30
  • 1
    No problem can copy code here :) Note that it's compatible with Visio 2010 (x64 as well) and above. For the older versions, please check the link. – Nikolay Nov 19 '15 at 22:03