小さなクラスを作る(1)~フォルダ選択機能

twitterのフォロワーさんからのアドヴァイス。

曰く、よく使う機能はクラスにしといた方がいいぜと。なるほど。今まで、よく使う処理をSubやFunctionにまとめて一つのモジュールに集めておいて、ライブラリ的に使っていたけど、結局、

どこに何を書いていたのか忘れる

というマヌケなことになっていた。

その点、クラスだとかなり擬人的なので、忘れにくいかも知れん。

で、さっそくやってみた。私の場合、ユーザーにフォルダを選ばせるという処理をよく使うので(しかも、やり方をよく忘れるw)、そんな役割のクラスを作ってみる。

f:id:akashi_keirin:20170304215650j:plain

クラスモジュールに「FoldePicker」という名前を付けて、以下のコードを書く。

Option Explicit

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

'アクセサ
Public Property Get gotFolder() As String
  gotFolder = gotFolder_
End Property
Public Property Get isCancelled() As Boolean
  isCancelled = isCancelled_
End Property

'コンストラクタ

'メソッド
Public Sub showFolderPicker()
'機能:フォルダ選択ダイアログボックスを表示し、選択されたフォルダパスを
'      gotFolderプロパティにセットする。引数なし。
'   キャンセルされると、isCancelledプロパティをTrueにする。
  With Application.FileDialog(msoFileDialogFolderPicker)  '……(1)
    If .Show = True Then                                  '……(2)
      gotFolder_ = .SelectedItems(1)                      '……(3)
    End If
  End With
  If gotFolder_ = "" Then                                 '……(4)
    MsgBox "キャンセルされました。"
    isCancelled_ = True                                   '……(5)
  Else
    isCancelled_ = False                                  '……(6)
  End If
End Sub

こんな感じ。

Application.FileDialogオブジェクト(?)で、引数に「msoFileDialogFolderPicker」を指定しているので、フォルダ選択ダイアログオブジェクトを指すってことでしょうか。

  • (1)でWithを使っているので、以下はEnd Withまでフォルダ選択ダイアログオブジェクトに対する操作。
  • (2)のIf文の条件の中でShowメソッドを実行。ユーザーがダイアログで[OK]ボタンを押したら、条件成立。
    コチラによると、ファイル ダイアログ ボックスを表示して、ユーザーが [アクション] ボタン (-1) または [キャンセル] ボタン (0) を押したかどうかを示す Long を返します。との由。
    つまり、[OK]ボタンが押されたら「-1(True)」が返るということ。
  • ユーザーがダイアログで[OK]を押したら、(3)でSelectedItemsプロパティ(=選択したフォルダのフルパス)が変数gotFolder_に代入される。
    フォルダ選択ダイアログでは、複数選択ができないので、SelectedItemsのインデックスは「1」を指定する。
  • (4)。キャンセルされると、gotFolder_には何も代入されていないことになる。
  • (5)でisCancelled_をTrueにする。
  • (6)は、gotFolder_にフォルダパスがセットされている場合なので、isCancelled_をFalseにしておく。
    一旦キャンセルした後、再度showFolderPickerメソッドを実行したら、isCancelled_がTrueのままになってしまうので。

動作確認のため、標準モジュールに以下のコードを書いて実行。

Public fdp As FolderPicker
Public Sub test()
  Set fdp = New FolderPicker                   '……(1)
  With fdp                                     '……(2)
    .showFolderPicker                         '……(3)
    If .isCancelled = True Then               '……(4)
      MsgBox "ズバリ、キャンセルしたでしょう!"
    Else
      Debug.Print "gotFolder = " & .gotFolder
      Debug.Print "Len(.gotFolder) = " & Len(.gotFolder)
      Debug.Print "InStrRev(.gotFolder, ""\"") = " & InStrRev(.gotFolder, "\")
      Debug.Print "Right(.gotFolder, Len(.gotFolder) - InStrRev(.gotFolder, ""\"")) = " & _
                  Right(.gotFolder, Len(.gotFolder) - InStrRev(.gotFolder, "\"))
      MsgBox "ズバリ、あなたが選んだフォルダは、「" & _
             Right(.gotFolder, Len(.gotFolder) - InStrRev(.gotFolder, "\")) & _
             "」フォルダでしょう!"           '……(5)
    End If
  End With
End Sub

一応説明。

  • (1)でFolderPickerクラスのインスタンスを生成。
  • ここからは、全てインスタンスfdpへの操作なので(2)でWithでまとめる。
  • (3)で、showFolderPickerメソッドを実行。
  • (4)。isCancelledプロパティがTrueだったら、メッセージを表示。
  • (5)。isCancelledプロパティがTrueでなかったら、フォルダ名を表示。
    フォルダ名だけを切り出す処理はちょっとややこしいので、後で。

んで、実行。

f:id:akashi_keirin:20170304215044j:plain

フォルダ選択ダイアログが表示され……、

f:id:akashi_keirin:20170304215052j:plain

フォルダを選んで[OK]をクリックすると……、

f:id:akashi_keirin:20170304215101j:plain

ほれ、この通り、選んだフォルダ名が表示された。

f:id:akashi_keirin:20170304215111j:plain

キャンセルすると、……

f:id:akashi_keirin:20170304215119j:plain

キャンセルしたことがバレる仕様w

f:id:akashi_keirin:20170304215125j:plain

ちなみに、フォルダ名だけを切り出すのはこんなカラクリ。

「フォルダ名は、フルパスのうち一番右にある「\」から右の文字列である」という考え方で切り出している。

今回の例だと、フルパスが

E:\個人用\ち~んw

の11文字。

一番右の「\」が前から7文字目。これはInStrRev関数で求めることができる。

11から7を引くと、4。よって、Right関数で右から4文字を抜き出してやると、めでたくフォルダ名「ち~んw」が得られる。

……とまあ、こんな感じでユーザーにフォルダを選択させてフォルダのフルパスを得るためのクラスを作ってみたけど、これで良いのだろうか……?

玄人の意見求む!