実践編1-3では、シートに表示されたフォルダパスからファイル名を取得しました。
ただ、フォルダパスを毎回入力するのは手間ですよね。
そこで、ファイルを保存するときなどに出てくるダイアログをVBAで表示させ、ユーザーにフォルダを選択させるような処理を行いたいと思います。
ダイアログを表示させるときに使うのが「FileDialogオブジェクト」です。
今回は次のような機能を追加していきます。
- シート上にボタンを設置する
- ボタンを押すとダイアログが表示する
- ダイアログからフォルダを選択し、シートにフォルダのパスをセットする
この機能を前回の「検索」ボタンの機能と組み合わせると、ユーザーはより使いやすくなります。
目次
フォルダを選択するVBAコード
まずは標準モジュールに以下のコードを追加します。
Sub GetFolderName()
Dim folderPath As String
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "検索したいフォルダを選択してください"
.AllowMultiSelect = False
If .Show = 0 Then
Exit Sub
End If
folderPath = .SelectedItems(1)
End With
ThisWorkbook.Worksheets("Sheet1").Cells(3, 1).Value = folderPath
End Sub
前回までとは別のプロシージャとして登録することで、シート上に別の処理を呼び出せるようにします。
次に、シートに上記のVBAを登録するためのボタンを設置します。
前回設置した「検索」ボタンの近くに「フォルダ選択」という名前で設置しています。
これで、フォルダ選択→検索という流れができました。
フォルダに関しては自分で入力することも可能ですので、その場合はフォルダ選択を利用しないということになります。
VBAコードを分け、それぞれの役割ごとにボタンを用意することで、柔軟な処理が行うことができます。
VBAコードの解説
今回の処理のポイントはFileDialogオブジェクトの使い方です。
ユーザーが選択したものをシートにセットするのですが、使用している人が予期しない行動をしてしまう場合もあるので、そのあたりを注意しながらコードを書いていきます。
フォルダを選択できるようにする
With Application.FileDialog(msoFileDialogFolderPicker)
今回はファイルではなく、フォルダを選択してもらいたいので、引数に「msoFileDialogFolderPicker」を指定します。
もし、ファイルを選択してもらいたい場合は「msoFileDialogFilerPicker」を指定すればOKです。
頭にある「With」は同じオブジェクトの処理を書くときに、オブジェクト名を省略して書きたいときに使います。
今回の場合だとFileDialogがオブジェクトになります。
このオブジェクトに対して、タイトルを設定し(Title)、複数選択できない設定をし(AllowMultiSelect) 、ダイアログを表示し(show)、選択したフォルダを取得(SelectedItems)しています。
この処理はすべて同じオブジェクトなので、「With」「End With」で囲むことでオブジェクト名を省略することできます。
フォルダを複数選べないようにする
.AllowMultiSelect = False
今回のダイアログを使った処理ではユーザーの操作が関係してきます。
フォルダを選択する場合、1つだけを選んでほしいところ、ユーザーが2つ以上選択してしまう可能性があります。
そこで、複数選択できないように設定することでエラーが起きないようにします。
「False」にすると複数選択できないようにできます。
先頭の「.」はWithで囲んだときには必ず付けます。
「.」の前にはFileDialogが本当は入るのですが、Withを使っているので省略することができます。
逆に言うと「.」があることで省略していることが分かるので、必ず付けるようにしてください。
キャンセルを選んだときの処理
If .Show = 0 Then
Exit Sub
End If
「show」でダイアログを表示することができます。
ダイアログ画面の右下には「OK」と「キャンセル」ボタンがあります。
「OK」ボタンを押したときは「True」、「キャンセル」ボタンを押したときは「False」が戻り値として返ってきます。
もし、このIF文の処理がない場合にキャンセルを押すと、取得するフォルダがないため、次の行の「フォルダを取得する」がエラーになります。
そこで、この戻り値を使って、「0」のとき、つまり「False」のときは終了するという処理にしています。
選択したフォルダを取得する
folderPath = .SelectedItems(1)
最後に選択したフォルダのパスを取得します。
取得には「SelectedItems」を使用します。
SelectedItemsはインデックス数を指定する必要があります。
今回は1つしか選択できないようにしていますが、複数選択することもあるので、インデックス数の指定ができるようになっています。
インデックスは「1」から始まるので、今回のように1つしか選択しない場合はSelectedItems(1)とします。
まとめ
今回の実践編では、FileDialogを使用してユーザーがフォルダを選択できるような処理を追加しました。
数行のコードでダイアログを表示させることができるので便利ですが、ユーザーの操作が入ると自分の想定外のことも起きるので、エラー対策が必要になります。
今回は最低限の設定しかしませんでしたが、自分でダイアログを使った処理を実装する場合は、ユーザーがどんな操作をするかをイメージしながらコードを書くようにしてください。