TL;DR —
Application.GetSaveAsFilenameshows the Save As dialog and returns the path the user chose as a string — it does not save anything. To actually write the file you still callSaveAs. On Cancel it returns the BooleanFalse, so declare the variableAs Variantand testIf path = False Then Exit Sub. And the file's real format comes from theFileFormatyou pass toSaveAs, not from the extension in the dialog.
Sub AskThenSave()
Dim path As Variant ' Variant, so cancel can return False
path = Application.GetSaveAsFilename( _
InitialFileName:="Report " & Format(Date, "yyyy-mm-dd"), _
FileFilter:="Excel Workbook (*.xlsx), *.xlsx")
If path = False Then Exit Sub ' user cancelled
ActiveWorkbook.SaveAs Filename:=path, FileFormat:=xlOpenXMLWorkbook ' YOU save
End Sub
GetSaveAsFilename is the exact mirror of GetOpenFilename: one asks which
file to open, this one asks where to save. And it shares the same headline surprise — it returns a
path, it does not save a file — plus one gotcha of its own about file formats that produces corrupt-looking
files if you miss it. If you have read the GetOpenFilename guide, most of this will feel familiar; the last
two sections are where the differences live.
What you'll learn
- The mental model that ties
GetSaveAsFilename,GetOpenFilenameandFileDialogtogether - Why it returns a path, not a saved file — and the
SaveAsline you still owe - The cancel trap again: it returns
False, so the variable must beAs Variant - Suggesting a default name and folder with
InitialFileName - The format trap: the extension the user sees is not what decides the file type
- When to use it versus the
FileDialogSaveAs type
The mental model: a sticky note that asks where to save
Like its sibling, GetSaveAsFilename hands the user a sticky note — this one asks "save where, and under
what name?" The user browses, types a name, clicks Save, and you get back the path they chose. Nothing is
written to disk:
path = Application.GetSaveAsFilename(...) ' returns a PATH string
ActiveWorkbook.SaveAs Filename:=path ' YOU write the file
The "GetSaveAsFilename didn't create a file" report is the same misunderstanding as its sibling's, flipped:
the function only collects the destination. The actual save — ActiveWorkbook.SaveAs,
Workbook.SaveCopyAs, or writing text with a FileSystemObject — is your
next line. Asking where to save and saving are two steps.
The cancel trap, once more: Dim As Variant
Cancel behaves exactly as in GetOpenFilename: the function returns the
Boolean False, so the variable must be able to hold either a path or a Boolean:
Dim path As Variant ' CORRECT - a path String OR the Boolean False
' Dim path As String ' WRONG - False becomes the text "False", so SaveAs writes a file named False
With As String, the cancelled False is coerced to the text "False", If path = False never fires,
and SaveAs cheerfully writes a workbook literally named False in the current directory. Declaring path As Variant and testing If path = False Then Exit Sub is the whole fix.
Suggesting a default name with InitialFileName
The best save dialogs open with a sensible name already filled in. That is the InitialFileName argument —
and it can carry a folder too, so the dialog opens where you want:
' Prefill a dated name in a specific folder
path = Application.GetSaveAsFilename( _
InitialFileName:="C:\Reports\Sales " & Format(Date, "yyyy-mm-dd") & ".xlsx", _
FileFilter:="Excel Workbook (*.xlsx), *.xlsx")
Using named arguments (InitialFileName:=, FileFilter:=) keeps the call readable, because
GetSaveAsFilename has several optional parameters and positional commas get hard to count. A prefilled,
dated name is a small touch that makes a macro feel finished.
The format trap: the extension is not the format
This is the gotcha unique to saving, and it catches people who assume the dialog's extension controls the
file type. It does not. GetSaveAsFilename returns a string; the real file format is decided by the
FileFormat argument you pass to SaveAs:
' MISMATCH - path ends in .xlsx but you tell SaveAs to write the old binary format
ActiveWorkbook.SaveAs Filename:="Book.xlsx", FileFormat:=xlExcel8 ' -> a file that won't open cleanly
' MATCH - extension and FileFormat agree
ActiveWorkbook.SaveAs Filename:="Book.xlsx", FileFormat:=xlOpenXMLWorkbook ' .xlsx
ActiveWorkbook.SaveAs Filename:="Book.xlsm", FileFormat:=xlOpenXMLWorkbookMacroEnabled ' .xlsm
If the extension on the path and the FileFormat constant disagree, Excel writes bytes in one format under
a name that claims another — and the file throws an error when someone double-clicks it. So decide the
format in your code and pass the matching FileFormat; do not assume the .xlsx the user saw in the
dialog did anything. If you offer several filters, read which one the user chose (via the FilterIndex
they leave the dialog on) and pick the FileFormat to match.
GetSaveAsFilename or FileDialog SaveAs? Pick by control
For "ask where to save and give me the path," GetSaveAsFilename is the direct, one-line tool. Reach for
FileDialog with msoFileDialogSaveAs when you want the dialog object — for its
.Execute method, or to keep the same .SelectedItems reading style you use elsewhere. To ask what to
open instead of where to save, the mirror is GetOpenFilename. All three
return a path and leave the acting to you.
How ExcelMaster helps
The mistakes here are the ones that only show up later: a workbook named False from an unguarded cancel,
and a file that will not open because the extension and FileFormat disagreed. Neither raises an error
when the macro runs — they surface when someone tries to use the file.
ExcelMaster lets you describe
the outcome — "let me choose where to save this sheet as a dated CSV" — and it writes the
GetSaveAsFilename call with the Variant cancel guard, a sensible default name, and a SaveAs whose
FileFormat matches the extension. You keep the workbook and the code.
Frequently asked questions
How do I use GetSaveAsFilename in Excel VBA?
Call path = Application.GetSaveAsFilename(InitialFileName, FileFilter, FilterIndex, Title). Declare path As Variant, test If path = False Then Exit Sub to catch a cancel, then save with
ActiveWorkbook.SaveAs Filename:=path, FileFormat:=.... The function only returns the chosen path — it does
not save the file itself.
Why does GetSaveAsFilename not save the file?
Because it is only meant to collect the destination path, not to write anything. It shows the Save As
dialog and returns the path the user chose. You perform the actual save on the next line —
ActiveWorkbook.SaveAs Filename:=path for a workbook, or a
FileSystemObject for text. Asking where to save and saving are separate
steps.
How do I set a default file name in the Save As dialog?
Pass the InitialFileName argument: Application.GetSaveAsFilename(InitialFileName:="Report.xlsx"). It can
include a folder as well as a name, so "C:\Reports\Report " & Format(Date, "yyyy-mm-dd") & ".xlsx" opens
the dialog in that folder with a dated name prefilled and ready to accept or edit.
How do I detect Cancel in GetSaveAsFilename?
Declare the variable As Variant and test If path = False Then Exit Sub. On cancel the function returns
the Boolean False; on success it returns a path string. With an As String variable the False is
coerced to the text "False", the check never fires, and SaveAs writes a file literally named False.
Why does my saved file not open after using GetSaveAsFilename?
Almost always because the extension on the path and the FileFormat you passed to SaveAs disagree — for
example a .xlsx name saved with FileFormat:=xlExcel8. Excel writes one format under a name that claims
another, and the file errors on open. Decide the format in code and pass the matching FileFormat
constant (xlOpenXMLWorkbook for .xlsx, xlOpenXMLWorkbookMacroEnabled for .xlsm).
Tested in
Tested in: Excel 365 (Windows 11), VBA 7.1 — last verified 2026-09-26.
Related guides: VBA GetOpenFilename · VBA FileDialog · VBA Save Workbook · VBA InputBox · VBA FileSystemObject · VBA Workbook
