エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

【本日のミッション】

Excel VBA を使って「名前を付けて保存」ダイアログボックスを表示させ、任意のファイル名でファイルを保存せよ。
「キャンセル」を選択してもエラーが出ないようにするべし!

ミッションの概要

「名前を付けて保存」ダイアログボックスを表示させ、任意のファイル名でファイルを保存せよ、というのが今回のミッションです。

ダイアログのタイトルや、ファイルの種類を自分好みにカスタマイズしましょう。
また、ダイアログで「キャンセル」した場合の処理も考えましょう。

【Excelブック(.xlsx)で保存】
エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

【Excelマクロ(.xlsm)で保存】
エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

■■■スポンサーリンク■■■

プロシージャ

Sub ダイアログからファイルを保存する()

    Dim fn As String    'ファイル名

    '■ダイアログ表示
    fn = Application.GetSaveAsFilename(InitialFileName:="お好みのファイル名に変更してください.xlsx", FileFilter:="Excelブック,*.xlsx,Excelマクロ,*.xlsm", Title:="お好みのファイル名で保存してください♪")

    '■ファイルが選択された場合は開く
    If fn <> "False" Then
    
        '■拡張子が「.xlsx」の場合
        If Mid(fn, InStrRev(fn, ".")) = ".xlsx" Then
            Application.DisplayAlerts = False       'マクロファイル「.xlsm」を「.xlsx」に保存確認のダイアログを非表示にする
            ActiveWorkbook.SaveAs Filename:=fn, FileFormat:=xlOpenXMLWorkbook
            Application.DisplayAlerts = True        'マクロファイル「.xlsm」を「.xlsx」に保存確認のダイアログを非表示にする を解除
        
        '■拡張子が「.xlsm」の場合
        ElseIf Mid(fn, InStrRev(fn, ".")) = ".xlsm" Then
            ActiveWorkbook.SaveAs Filename:=fn, FileFormat:=xlOpenXMLWorkbookMacroEnabled
        End If
    End If
End Sub

記入したプロシージャ(Sub~End Subまで)のどこかにカーソルを置いてF5キーをクリックしてください。

ダイアログが開き、ファイル名を指定して保存できますし、キャンセルすると何もおこりませんね♪

■■■スポンサーリンク■■■

Application.GetSaveAsFilenameメソッド

GetSaveAsFilenameメソッドは、ファイル名を取得するために「名前を付けて保存」ダイアログボックスを表示させます。

ダイアログには「保存」ボタンがありますが、これをクリックした時点ではファイルは保存されません。

GetSaveAsFilenameメソッドで取得したファイル名で、保存処理を行う必要があります。

また、「キャンセル」ボタンがクリックされた場合は「False」を返します。

Application.GetSaveAsFilename(InitialFilenameFileFilter, FilterIndex, Title, ButtonText)

引数名説明省略
InitialFilename「ファイル名」に表示される既定値を指定します。 この引数を省略すると、作業中のブックの名前が使われます
FileFilterファイルの種類・拡張子を指定する文字列(ファイルフィルター文字列)を指定します。
省略すると “すべてのファイル (*.*)”になります。
FilterIndex引数FileFilterで指定したファイルフィルター文字列の中で、1から何番目のFileFilterを既定値とするかを指定します。
省略または、引数FileFilter文字列の数より大きい数値を指定すると、最初のFileFilter文字列が既定値となります。
Titleダイアログボックスのタイトルを指定します。
省略すると “名前を付けて保存” になります。
ButtonTextMacintosh でのみ指定できます

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

今回のコードはこんな感じに記述しています。
必要な引数だけ「引数名:=引数の値」と指定することで、引数の順番を気にしなくて済みます。省略する第3引数は記述しません。

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

「引数名:=」を使用しない場合は、下記の通りになります。
引数を1つ目から順番に並べ、第3引数は省略しているので空欄にしています。

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

InitialFileName

「ファイル名」に表示される既定値を指定します。 この引数を省略すると、作業中のブックの名前が使われます

Application.GetSaveAsFilename(InitialFileName:="お好みのファイル名に変更してください.xlsx", FileFilter:="Excelブック,*.xlsx,Excelマクロ,*.xlsm")

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

ここで大切なポイント2つ。

  • 「InitialFileName」を使うときには「FileFilter」も指定する
  • 「InitialFileName」の拡張子を「FileFilter」の一つ目の拡張子と同じにする。

「InitialFileName」を使うときには「FileFilter」も指定する

InitialFileNameを指定しても、FileFilterを指定していないと、ファイル名は空になります。

Application.GetSaveAsFilename(InitialFileName:="お好みのファイル名に変更してください.xlsx")

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

「InitialFileName」の拡張子を「FileFilter」の一つ目の拡張子と同じにする。

InitialFileNameの拡張子と、FileFilterの一つ目の拡張子が一致していない時は、ファイル名は空になります。

Application.GetSaveAsFilename(InitialFileName:="お好みのファイル名に変更してください.xlsm", FileFilter:="Excelブック,*.xlsx,Excelマクロ,*.xlsm")

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

FileFilter

ファイルの種類・拡張子を指定する文字列です。
省略すると “すべてのファイル (*.*)”になりますが、選択するファイルの種類が決まっているなら、ダイアログに表示されるファイルが限定されるので、ファイルを選択しやすくなります。

ファイルの種類1つにつき、下記2つの情報をセットにして指定します。
指定するときは、2つの情報の間にカンマ「,」を入れます。
拡張子指定時に使用するワイルドカードの使い方についてはこちらを参照→ワイルドカードとは。使い方いろいろ。(Excel)

  • ファイルの種類を指定する文字列
  • ファイルの拡張子
Application.GetSaveAsFilename(FileFilter:="ファイルの種類を指定する文字列,ファイルの拡張子")
Application.GetSaveAsFilename(FileFilter:="Excelブック,*.xlsx")

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

1つのファイルの種類に、複数の拡張子を表示する場合は、拡張子の間にセミコロン「;」を入れます。

Application.GetSaveAsFilename(FileFilter:="テキストファイル,*.txt;*.csv")

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

複数のファイルの種類を表示する場合は、「ファイルの種類,拡張子」のセットをカンマ「,」で区切ります。カンマだらけになってしまいます。

Application.GetOpenFilename("ファイルの種類1,拡張子1,ファイルの種類2,拡張子2,ファイルの種類3,拡張子3")
Application.GetSaveAsFilename(FileFilter:="Excelブック,*.xlsx,Excelマクロ,*.xlsm")

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

もしも、こんなおふざけな指定をしてしまっても・・・

Application.GetSaveAsFilename(FileFilter:="えくせる,*.xlsx,まくろ,*.xlsm")

指定した通りの内容で表示されます。
エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

でも、かっこよく指定したい!という場合は、Excelの「ファイルを開く」ダイアログボックスのファイルの種類の文字をマネしておきましょう。誰からも突っ込まれないでしょう。

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

■■■スポンサーリンク■■■

FilterIndex

引数FileFilterで指定したファイルフィルタ文字列の中で、1から何番目のFileFilterを既定値とするかを指定します。

今回のように省略または、引数FileFilter文字列の数より大きい数値を指定すると、最初のFileFilter文字列が既定値となります。

Application.GetSaveAsFilename(InitialFileName:="お好みのファイル名に変更してください.xlsx", FileFilter:="Excelブック,*.xlsx,Excelマクロ,*.xlsm", Title:="お好みのファイル名で保存してください♪")

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

2番目のファイルの種類を規定値としたい場合は下記のようにします。

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

Title

ダイアログの上のバーに表示される文字です。
省略すると “名前を付けて保存”になるのですが、せっかくなのでメッセージ風にしてみました。

Application.GetSaveAsFilename(Title:="お好みのファイル名で保存してください♪")

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

「実行時エラー ’13′:型が一致しません。」が出る原因

「引数名:=」を使用しない場合、引数の順番を間違えたり、省略する引数の場所にもカンマ「,,」を入れなかったりすると

「実行時エラー ’13′:
型が一致しません。」

のエラーが表示されるので、注意が必要です。

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

■■■スポンサーリンク■■■

エラー「次の機能はマクロなしのブックに保存できません」

なぜエラーが出るのか

「次の機能はマクロなしのブックに保存できません
・VB プロジェクト
これらの機能が含まれるファイルを保存する場合は、[いいえ]をクリックし、[ファイルの種類]ボックスでマクロ有効ファイルの種類を選択してください。マクロなしのブックとして保存する場合は、[はい]をクリックしてください。」

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

というエラーですが、マクロを含むファイルを標準ファイル形式「.xlsx」で保存しようとしていることへの警告です。

確かに、マクロを含むファイルを「.xlsx」で保存してしまうと、マクロが消えてしまいます。

今回は、「マクロが消えてしまっても大丈夫」ということを理解した上で、「.xlsx」で保存しています。(今記載しているコードも消えてしまうのでご注意ください。)

エラーを表示させない方法

このエラーを表示させないためには、SaveAsの前に「Application.DisplayAlerts = False」を挿入します。これで、エラーダイアログが表示されなくなります。

!これを使用するとマクロの含まれないファイルになってしまうので、覚悟の上、ご使用ください!

SaveAsの処理の後には「Application.DisplayAlerts = True」を挿入して、エラーダイアログが表示されるようにしておきます。これ以外のエラーを見逃してしまっては大変ですから。

Application.DisplayAlerts = False       'マクロファイル「.xlsm」を「.xlsx」に保存確認のダイアログを非表示にする
ActiveWorkbook.SaveAs Filename:=fn, FileFormat:=xlOpenXMLWorkbook
Application.DisplayAlerts = True        'マクロファイル「.xlsm」を「.xlsx」に保存確認のダイアログを非表示にする を解除

エラー「実行時エラー’1004」

なぜエラーが出るのか

「実行時エラー ’1004′;
この拡張子は、選択したファイル形式には使用できません。[ファイル名]ボックスでファイル拡張子を変更するか、[ファイルの種類]ボックスで別のファイル形式を選択してください。」

エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

というエラーですが、今回の場合はマクロを含むファイル形式「.xlsm」を標準ファイル形式「.xlsx」で保存しようとするとエラーが出ます。

エラーを表示させない方法

このエラーを表示させないために、拡張子が「.xlsx」の場合と「.xlsm」の場合の場合で、処理方法を変えています。

拡張子が「.xlsx」の場合はFileFormatを「xlOpenXMLWorkbook」、「.xlsm」の場合はFileFormatを「xlOpenXMLWorkbookMacroEnabled」という風にきちんと明記してあげます。

'■拡張子が「.xlsx」の場合
If Mid(fn, InStrRev(fn, ".")) = ".xlsx" Then
    Application.DisplayAlerts = False       
    ActiveWorkbook.SaveAs Filename:=fn, FileFormat:=xlOpenXMLWorkbook
    Application.DisplayAlerts = True        
        
'■拡張子が「.xlsm」の場合
ElseIf Mid(fn, InStrRev(fn, ".")) = ".xlsm" Then
    ActiveWorkbook.SaveAs Filename:=fn, FileFormat:=xlOpenXMLWorkbookMacroEnabled
End If

【参考】

指定したフォルダ内のファイル名全てを取得(Excel VBA)
変数でよく使われる「buf」「tmp」の意味
Dir関数が取得するファイルの順番
指定したフォルダ内のフォルダ名全てをGetAttrを使って「エラー53 ファイルが見つかりません。」を出さずに取得(Excel VBA)
GetAttr関数とAnd演算子でビット演算の使い方 ファイルやフォルダの属性を取得
フォルダ名だけを取得したい時に出てくる 「.」 と 「..」 とは?
指定したフォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)
CreateObject(“Scripting.FileSystemObject”) を使ってサブフォルダを取得
再帰処理とは?フォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)
指定したフォルダ内のサブフォルダのフォルダ名を全部取得(Excel VBA)
再帰処理とは?フォルダ内のサブフォルダのフォルダ名を全部取得(Excel VBA)
参照渡し「ByRef」と値渡し「ByVal」の違い(Excel VBA)
ファイルのフルパスからファイル名のみを取得 InStrRev関数(Excel VBA)
指定したフォルダの全ての階層のフォルダ名・サブフォルダ名・ファイル名を取得(Excel VBA)
FileSystemObjectとは?CreateObject 関数 FolderExists・GetFolderの使い方
FileSystemObject CreateObject関数を使う方法・ 参照設定を使う方法 違いを理解してエラー防止
再帰処理とは?指定したフォルダの全ての階層のフォルダ名・サブフォルダ名・ファイル名を取得(Excel VBA)
ファイルのフルパスからファイル名のみを取得 Split関数(Excel VBA)
Callステートメントとは 引数 括弧()の使い方(Excel VBA)
指定したフォルダ内から「特定の文字を含まないファイル名」を取得(Excel VBA)
ワイルドカードとは。使い方いろいろ。(Excel)
Dir関数の使い方。ファイル名やフォルダ名の取得方法。(Excel VBA)
指定したフォルダのファイル名を取得し、そのファイル名を一括で変換(Excel VBA)
Excel起動時に「コンパイルエラー」。64ビット システムで Declareステートメントに、PtrSafe属性を設定(Excel VBA )
「ファイルを開く」ダイアログボックス から ファイル名を取得(Excel VBA)
「ファイルを開く」ダイアログボックス から 複数 ファイル名を取得(Excel VBA)
指定フォルダ内のサブフォルダ全てをフォルダ構成のみ(空フォルダ)を別フォルダにコピー(Excel VBA)
再帰処理とは?指定フォルダ内のサブフォルダ全てをフォルダ構成のみ(空フォルダ)を別フォルダにコピー(Excel VBA)
エクセル 「名前を付けて保存」ダイアログを表示して任意のファイル名で保存(Excel VBA)

■■■スポンサーリンク■■■