Show file browse for save or open in Visual Basic 6 (VBA)
Excel VBA macro provides a helper function to browse the name of the file to save Application.GetSaveAsFilename or open Application.GetOpenAsFilename. These functions however only available in Excel VBA macros and is not available in other environments.
This example demonstrates how create a generic functions to browse for save or open file.
Private Declare PtrSafe Function GetSaveFileName Lib "comdlg32.dll" Alias "GetSaveFileNameA" (pOpenfilename As OPENFILENAME) As Boolean
Private Declare PtrSafe Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameA" (pOpenfilename 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 LongPtr
nFileOffset As Integer
nFileExtension As Integer
lpstrDefExt As String
lCustData As Long
lpfnHook As Long
lpTemplateName As String
End Type
Const FILTER As String = "Text Files (*.txt)|*.txt|PNG Image Files (*.png)|*.png|All Files (*.*)|*.*"
Sub main()
Dim filePath As String
filePath = BrowseForFileSave("Select file path to save", FILTER)
If filePath <> "" Then
Debug.Print "Selected save file path: " & filePath
Else
Debug.Print "No save file selected"
End If
filePath = BrowseForFileOpen("Select file path to open", FILTER)
If filePath <> "" Then
Debug.Print "Selected open file path: " & filePath
Else
Debug.Print "No open file selected"
End If
End Sub
Function BrowseForFileSave(title As String, filters As String) As String
BrowseForFileSave = BrowseForFile(title, filters, True)
End Function
Function BrowseForFileOpen(title As String, filters As String) As String
BrowseForFileOpen = BrowseForFile(title, filters, False)
End Function
Function BrowseForFile(title As String, filters As String, save As Boolean) As String
Dim ofn As OPENFILENAME
Const FILE_PATH_BUFFER_SIZE As Integer = 260
ofn.lpstrFilter = Replace(filters, "|", Chr(0)) & Chr(0)
ofn.lpstrTitle = title
ofn.nMaxFile = FILE_PATH_BUFFER_SIZE
ofn.nMaxFileTitle = FILE_PATH_BUFFER_SIZE
ofn.lpstrFile = String(FILE_PATH_BUFFER_SIZE, Chr(0))
ofn.lStructSize = LenB(ofn)
Dim res As Boolean
If save Then
res = GetSaveFileName(ofn)
Else
res = GetOpenFileName(ofn)
End If
If res Then
Dim filePath As String
filePath = Left(ofn.lpstrFile, InStr(ofn.lpstrFile, vbNullChar) - 1)
If save Then
Dim vFilters As Variant
vFilters = Split(FILTER, "|")
Dim ext As String
ext = vFilters((ofn.nFilterIndex - 1) * 2 + 1)
ext = Right(ext, Len(ext) - InStrRev(ext, ".") + 1)
If LCase(Right(filePath, Len(ext))) <> LCase(ext) Then
filePath = filePath & ext
End If
End If
BrowseForFile = filePath
Else
BrowseForFile = ""
End If
End Function