小さなクラスを作る(3)~ファイルを選択させる

ファイルを選択させるやつも作ってみた。

f:id:akashi_keirin:20170305092333j:plain

例によってクラスモジュールを挿入。オブジェクト名はFilePickerにした。

クラスモジュールのコードは下記の通り。

Option Explicit

'フィールド
Private gotFileFullPath_ As String
Private isCancelled_ As Boolean

'アクセサ
Public Property Get gotFileFullPath() As String
  gotFileFullPath = gotFileFullPath_
End Property
Public Property Get gotFileName() As String         '……(1)
  gotFileName = Right(gotFileFullPath_, _
                     (Len(gotFileFullPath) - InStrRev(gotFileFullPath, "\")))
End Property
Public Property Get isCancelled() As Boolean
  isCancelled = isCancelled_
End Property

'コンストラクタ
Private Sub Class_Initialize()
  isCancelled_ = False
End Sub

'メソッド
Public Sub showFilePicker(ByVal titleStr As String)
  Dim fileFullPath As Variant                       '……(2)
  fileFullPath = Application.GetOpenFilename(Title:=titleStr)
  If fileFullPath = False Then                      '……(3)
    isCancelled_ = True
    gotFileFullPath_ = ""
  Else
    isCancelled_ = False
    gotFileFullPath_ = fileFullPath
  End If
End Sub

もはやほとんど解説の必要もないと思うので、要点だけ。

  • (1)は、gotFileNameプロパティの取得だが、Privateの仮変数を使っていない。フルパスが分かったら自ずと決まるものなので、必要なときのみ演算するようにした方がいいと思いました。「アホか」と思った上級者の方、ぜひご指摘ください。
  • (2)でGetOpenFileNameの結果を受け取る変数をVariant型にしている。これは、ファイル選択ダイアログで[キャンセル]が選ばれると、Booleanの値を返すため。Variantとか、雑な仕事のような気がしてあんまり使いたくないんだけど。
  • (3)はだから、[キャンセル]が選ばれたとき、ということ。isCancelled_をTrueにして、gotFileFullPath_には""を入れている。

標準モジュールに下記のコードを書いて実行。

Public flp As FilePicker
Sub test03()
  Set flp = New FilePicker
  With flp
    flp.showFilePicker "ファイルを選べ。"
    If .isCancelled = False Then
      MsgBox "ファイルのフルパス:" & .gotFileFullPath & vbCrLf & _
             "ファイル名:" & .gotFileName
    Else
      MsgBox "キャンセルされとるよ。"
    End If
  End With
End Sub

f:id:akashi_keirin:20170305094537j:plain

ファイルを選ぶと、

f:id:akashi_keirin:20170305092209j:plain

gotFileFullPathプロパティには選んだファイルのフルパスが、gotFileNameプロパティには選んだファイルのファイル名が、それぞれセットされていることが分かる。

引数でFileFilterとかMultiSelectに対応できるようにするなど、改良次第でかなり便利になりそうだ。

コチラのページ(mougモーグ)を参考に、追々改良していこう。

@akashi_keirin on Twitter