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

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

これまで

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

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

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

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

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

の集大成。

ユーザが選択したファイル名のコレクションを取得するメソッド

これまでの議論を踏まえてメソッド化。

一挙公開。

リスト1
Public Function getSelectedFilePath( _
   Optional ByVal isMultiSelect As Boolean = False, _
   Optional ByVal filterType As String = "全てのファイル", _
   Optional ByVal extString As String = "*.*", _
   Optional ByVal defaultFolderPath As String, _
   Optional ByVal titleOfDialog As String = "ファイル選択") _
                                    As FileDialogSelectedItems
   
  If filterType = "全てのファイル" Then extString = "*.*"
  If extString = "*.*" Then filterType = "全てのファイル"
   
'///第1引数filterTypeは、「"Excelワークブック","全てのファイル"」の形で渡す'
  Dim typeArr() As String
  typeArr = Split(filterType, ",")
    
'///第2引数extStringは、「"*.gif; *.jpg; *.jpeg,*.*"」の形で渡す'
  Dim extArr() As String
  extArr = Split(extString, ",")
  
  '第1引数と第2引数の数が合っていなければExit'
  If UBound(typeArr) <> UBound(extArr) Then GoTo Finalizer
  
  If fsObj Is Nothing Then _
    Set fsObj = New FileSystemObject
  
  Dim ret As FileDialogSelectedItems
  '第4引数省略なら最初に表示するディレクトリをこのブックのある'
  'ディレクトリにする                                          '
  If defaultFolderPath = "" Then _
    defaultFolderPath = ThisWorkbook.Path
  '第4引数のフォルダが不存在ならば(以下略)'
  If Not fsObj.FolderExists(defaultFolderPath) Then _
    defaultFolderPath = ThisWorkbook.Path
  
  Dim isSelected As Boolean
  Dim fpDialog As FileDialog
  Set fpDialog = Application.FileDialog(msoFileDialogFilePicker)
  With fpDialog
    'ダイアログボックスのタイトルを設定'
    .Title = titleOfDialog
    '複数選択の設定'
    If isMultiSelect Then .AllowMultiSelect = True
    'デフォルト表示フォルダの設定'
    .InitialFileName = defaultFolderPath
    '一旦ファイルフィルタをクリア'
    Call .Filters.Clear
    'ファイルフィルタを作成'
    Dim i As Long
    For i = 0 To UBound(typeArr)
      Call .Filters.Add(typeArr(i), extArr(i), i + 1)
    Next
    'ボックスを表示して、選択が為されたかどうかを取得'
    isSelected = .Show
    'ファイル選択されていたら、コレクションを取得'
    If isSelected Then Set ret = .SelectedItems
    '再度ファイルフィルタをクリア'
    Call .Filters.Clear
  End With
Finalizer:
  '取得した値を返却'
  Set getSelectedFilePath = ret
End Function

かなり細かくコメントを入れたので、詳しい解説は省略。

かなり引数が多くなってしまったが、せめてこれぐらいは設定する余地がないと、使いにくいだろう。

使ってみる

次のコードで実行。

Private Sub testGetSelectedFilePath()
  Dim fileNames As FileDialogSelectedItems
  Set fileNames = getSelectedFilePath( _
                    isMultiSelect:=True, _
                    filterType:="ち~んw,音楽ファイル,全てのファイル", _
                    extString:="*.www,*.flac;*.mp3,*.*", _
                    defaultFolderPath:="D:\Music\ACCEPT", _
                    titleOfDialog:="ち~んw")
  Dim i As Long
  For i = 1 To fileNames.Count
    Debug.Print fileNames(i)
  Next
End Sub

ファイル選択ダイアログで選択したファイル名(フルパス)をイミディエイトに列挙する。なんと、たったこれだけ。

getSelectedFilePathメソッドがFileDialogSelectedItemsオブジェクト(実体はString型の要素を格納したCollection。)を返すので、

Dim i As Long
For i = 1 To fileNames.Count
  Debug.Print fileNames(i)
Next

こんなシンプルすぎるコードでファイル名の取り出しが可能になる。

実行すると、

f:id:akashi_keirin:20190923073105g:plain

こうなって、

f:id:akashi_keirin:20190923073102j:plain

こうなる。

おわりに

引数の指定がちょっとめんどくさいんですが、割と便利なんではないかと思います。