フォルダ選択ダイアログを表示させるFunction

フォルダを選択させてフォルダパスを取得するFunction

ファイルをリネームするマクロを作るにあたり、保存先をその都度選べるようにした方が汎用性が高いと思ったので、Functionにしてみようと思った。

すでに

akashi-keirin.hatenablog.com

このときにクラスは作ってみたけれど、改めて復習も兼ねて。

Application.FileDialogプロパティ

まず、Application.FileDialogプロパティの復習。

コチラによると、

Application.FileDialog プロパティ (Excel)

ファイル ダイアログ ボックスの 1 つのインスタンスを表す FileDialog オブジェクトを取得します。

構文

式 . FileDialog( fileDialogType )

式Application オブジェクトを表す変数です。

パラメーター
MsoFileDialogType列挙体
名前 必須 / 省略可能 データ型 説明
fileDialogType 必須 MsoFileDialogType ファイル ダイアログの種類です。

おおお! 昔はたぶん意味が分かっていなかった説明が、今は手に取るように分かるぞ!

かつては、

ApplicationオブジェクトのFileDialogプロパティを参照したらFileDialogオブジェクトが取得できる

って意味が分からんかったんだよなー。

んで、オブジェクトを取得したら、そいつに仕事をさせにゃならん。FileDialogオブジェクトの場合は、まずダイアログボックスを表示させなくてはいけない。

FileDialogオブジェクトを表示させるメソッドがShowメソッド。

コチラによると、

ファイル ダイアログ ボックスを表示して、ユーザーが [ アクション] ボタン (-1) または [ キャンセル] ボタン (0) を押したかどうかを示す Long を返します。

とのこと。

これも昔は意味が分かってなかったところだなあ。

特にVBAの場合は、いわゆる「メソッド」に相当するものを「Sub」、「Function」と呼び分けているので、

返り値のあるメソッド

とか言われるとわけが分からなくなるのかも知れない。

ともかく、

  • Showメソッドが実行されるとダイアログボックスが表示される
  • ユーザーがファイルなりフォルダなりを選んで[OK]をクリックすると「-1」(True)が返り、
  • ユーザーが[キャンセル]をクリックすると「0」(False)が返る



ということを押さえておけばおkっぽい。

コーディング

以上のことを押さえてコーディングしてみた。

リスト1 標準モジュール
Public Function getSelectedFolderPath( _
                  Optional ByVal titleOfDialog As String = "フォルダ選択") _
                    As String    '……(1)'
  Dim isSelected As Boolean    '……(2)'
  With Application.FileDialog(msoFileDialogFolderPicker)
    If Not IsMissing(titleOfDialog) Then .Title = titleOfDialog    '……(3)'
    isSelected = .Show    '……(4)'
    If isSelected Then    '……(5)'
      getSelectedFolderPath = .SelectedItems(1)
    Else
      getSelectedFolderPath = ""
    End If
  End With
End Function

まず(1)の

Public Function getSelectedFolderPath( _
                  Optional ByVal titleOfDialog As String) As String

で引数と返り値の設定。

ダイアログのタイトル文字列を引数で渡せるようにしている。

ダイアログのタイトルを指定しなかったら、デフォルトのタイトルが設定されるのだが、それが「ファイルを開く」だったりするので、デフォルト値を設定している。

返り値はString型。選択したフォルダのパスの文字列が返る。

(2)の

Dim isSelected As Boolean

は、ダイアログでファイルが選択されたかどうかをぶち込む変数。

Showメソッドの返り値をぶち込む。

(3)の

If Not IsMissing(titleOfDialog) Then .Title = titleOfDialog

では、引数titleOfDialogが省略されていなければ、Application.FileDialogオブジェクトのTitleプロパティに渡された引数をセットする。

(4)の

isSelected = .Show

では、Application.FileDialogオブジェクトのShowメソッドを実行し、返り値をisSelectedにぶち込んでいる。

ユーザーが[OK]をクリックすればTrueが返り、[キャンセル]をクリックすればFalseが返ることになる。

あとは、(5)からの5行

If isSelected Then
  getSelectedFolderPath = .SelectedItems(1)
Else
  getSelectedFolderPath = ""
End If

で、Showメソッドの実行結果に応じた値をreturnしておしまい。

フォルダは一つしか選択できないので、Application.FileDialog.SelectedItemsコレクションのインデックス番号は必ず「1」になる。

isSelectedがFalseのとき、すなわち[キャンセル]がクリックされたときは、空の文字列が返ることになるので、呼び出し側のプロシージャでは条件分岐するなどの注意が必要。

ちなみに、ダイアログで何も選択せずに[OK]をクリックすると、最初に表示されたフォルダのパスが返る。

実験

イミディエイトに、

?getSelectedFolderPath("ち~んw")

と入力して[Enter]を押す。

f:id:akashi_keirin:20180204101233j:plain

ダイアログが表示されるので、ダイアログ上でフォルダを選んで[OK]をクリック。

f:id:akashi_keirin:20180204101244j:plain

んで、

f:id:akashi_keirin:20180204101253j:plain

ダイアログで[キャンセル]をクリックすると、

f:id:akashi_keirin:20180204101301j:plain

この通り。

おわりに

「学ビテ時ニ之ヲ習フ」とはまさにこのことだなあ。やっぱり、復習は大切です。

あ、あと、これはWordにも使用可能っす。

@akashi_keirin on Twitter