ユーザが選択したファイル名を取得する(5)

ユーザが選択したファイル名を取得する

一応、前回

akashi-keirin.hatenablog.com

のつづき。

FileDialogFiltersオブジェクトの設定

前々回のリスト1では、FileDialogFiltersオブジェクトを設定するのに

Dim fpDialog As FileDialog
Set fpDialog = Application.FileDialog(msoFileDialogFilePicker)
With fpDialog
  〔中略〕
  Call .Filters.Add("ち~んw", "*.www", 1)
  Call .Filters.Add("音楽ファイル", "*.flac;*.mp3", 2)
  Call .Filters.Add("全てのファイル", "*.*", 3)
  〔中略〕
End With

と、直接指定していた。これを引数で渡せるようにしたい。

配列を使う

[FileDialog].Filters.Addメソッドの引数は、「Description」、「Extention」、「Position」の三つ。

前二者を配列で受け取って、Filters.Addメソッドを実行するメソッドを作ってはどうだろうか。

リスト1
Private Function getFiltersAddedFileDialog( _
             ByVal targetDialog As FileDialog, _
             ByVal descriptionStrings As String, _
             ByVal extentionStrings As String) As FileDialog  '……(1)'
  Dim ret As FileDialog
  Set ret = targetDialog
  Dim descArr() As String    '……(2)'
  descArr = Split(descriptionStrings, ",")
  Dim extArr() As String
  extArr = Split(extentionStrings, ",")
  Dim i As Long
  Call ret.Filters.Clear    '……(3)'
  For i = LBound(descArr) To UBound(extArr)
    With ret
      Call .Filters.Add(descArr(i), extArr(i), i + 1)
    End With
  Next
  Set getFiltersAddedFileDialog = ret    '……(4)'
End Function

まずは(1)の

Private Function getFiltersAddedFileDialog( _
             ByVal targetDialog As FileDialog, _
             ByVal descriptionStrings As String, _
             ByVal extentionStrings As String) As FileDialog

で引数と返り値の設定。

第1引数targetDialogで対象のFileDialogオブジェクトを受け取る。

第2引数descriptionStringsでは、ファイルフィルタの説明用文字列(「すべてのファイル」みたいなやつ)のセットを受け取る。ただし、配列ではなく、文字列を「,」(半角カンマ)で区切ったセットにする。

第2引数extentionStringsでは、フィルタ用の拡張子の文字列を受け取る。これも第2引数同様、「,」(半角カンマ)で区切ったものを受け取るようにする。

(2)の

Dim descArr() As String
descArr = Split(descriptionStrings, ",")
Dim extArr() As String
extArr = Split(extentionStrings, ",")

では、第2、第3引数で受け取った文字列をSplitを用いて配列化。

見ての通り、単純に配列化しているだけなので、ファイルフィルタの説明用文字列と拡張子とが正しく対応するかどうかは、このメソッドの利用者次第、ということになる。

次に、(3)の

Call ret.Filters.Clear
For i = LBound(descArr) To UBound(extArr)
  With ret
    Call .Filters.Add(descArr(i), extArr(i), i + 1)
  End With
Next

で、配列から取り出した値をFilters.Addメソッドの引数DescriptionExtentionに渡して実行。

Positionは、第1引数・第2引数の組み立て方次第、とした。

あとは、(4)の

Set getFiltersAddedFileDialog = ret

で設定を済ませたFileDialogオブジェクトを返しておしまい。

使ってみる

さっそく、次のコードで利用してみる。

スト2
Private Sub test()
  Dim fpDialog As FileDialog
  Set fpDialog = Application.FileDialog(msoFileDialogFilePicker)
  With fpDialog
    .Title = "ち~んw"
    .InitialFileName = "D:\Music\ACCEPT"
  End With
  Set fpDialog = getFiltersAddedFileDialog( _
                   targetDialog:=fpDialog, _
                   descriptionStrings:="ち~んw,音楽ファイル,全てのファイル", _
                   extentionStrings:="*.www,*.flac;*.mp3,*.*")
  Call fpDialog.Show

リスト1のgetFiltersAddedFileDialogメソッドに、それぞれ

第1引数:targetDialog

FileDialogオブジェクトをぶち込んだfpDialog

第2引数:descriptionStrings

ファイルフィルタの説明用文字列三つのセット(「ち~んw」、「音楽ファイル」、「全てのファイル」をカンマ区切りでつないだもの)

第3引数:extentionStrings

拡張子三つのセット(「*.www」、「*.flac;*.mp3」、「*.*」をカンマ区切りでつないだもの)

を渡している。

もちろん、このgetFiltersAddedFileDialog実行後は、Showメソッドを実行するだけなので、このリスト2を実行したところで特段何かが起こるわけではない。本当に単にファイル選択ダイアログボックスを表示するだけw

実行

スト2を実行して表示されたダイアログボックスが

f:id:akashi_keirin:20190923070217j:plain

これ。

ちゃんと意図どおりのファイルフィルタが設定できている。

おわりに

利用者が引数をちゃんと渡してくれることが前提になってしまっているのがちょっとアレかも知れませんが、このあたり、Foolproofにしようと思ったら、それなりの規模の〈フィルタの説明/対応する拡張子〉リストが必要になるのではないでしょうか。