似たようなプロシージャを一つにまとめてみる
昨日は、ユーザーフォーム上でフォルダの絞り込みを行い、最終的にファイルを選択するところまで作成した。
infoment.hatenablog.com
これを行うにあたり、似たようなサブプロシージャを4つも作ってしまった。そこで今日は、これを一つにまとめてみる。
クラスモジュール(SeaquenceClass)
昨日までに作成したのは、以下の4つ。
指定パスのサブフォルダ名を配列で取得。
Public Function GetSubFoldersSeq(folder_path As String) As Variant Dim TempCol As Collection Set TempCol = GetSubFoldersCol(folder_path) If TempCol.Count >= 1 Then GetSubFoldersSeq = ToArray(TempCol) Else GetSubFoldersSeq = Array() End If End Function
指定パスのサブフォルダ名をコレクションで取得。
Public Function GetSubFoldersCol(folder_path As String) As Collection ' Microsoft Scripting Runtimeの参照設定要 Dim FSO As FileSystemObject Set FSO = New FileSystemObject Dim TempCol As Collection Set TempCol = New Collection Dim myFolder As Folder For Each myFolder In FSO.GetFolder(folder_path).SubFolders TempCol.Add myFolder.Name Next Set GetSubFoldersCol = TempCol End Function
指定パスのフォルダ内にあるファイル名を配列で取得。
Public Function GetFilesSeq(folder_path As String) As Variant Dim TempCol As Collection Set TempCol = GetFilesCol(folder_path) If TempCol.Count >= 1 Then GetFilesSeq = ToArray(TempCol) Else GetFilesSeq = Array() End If End Function
指定パスのフォルダ内にあるファイル名をコレクションで取得。
Public Function GetFilesCol(folder_path As String) As Collection ' Microsoft Scripting Runtimeの参照設定要 Dim FSO As FileSystemObject Set FSO = New FileSystemObject Dim TempCol As Collection Set TempCol = New Collection Dim myFile As File For Each myFile In FSO.GetFolder(folder_path).Files TempCol.Add myFile.Name Next Set GetFilesCol = TempCol End Function
これを一つにまとめるために、最近自分の中で流行りの列挙型を用いてみる。
標準モジュール
' 取得する対象(フォルダ名か、ファイル名か) Public Enum ReturnGroup myVbFolder myVbFile End Enum ' 何に格納するか(配列か、コレクションか) Public Enum ReturnType myVbSeq myVbCol End Enum
次に、先ほどの4つを統合する。作戦は、こうだ。
- 対象がフォルダ名なのかファイル名なのか、引数で判断。
- どちらにしても、とにかくコレクションに格納。
- 戻り値は配列なのかコレクションなのか、引数で判断。
- コレクションだったらそのまま。配列なら、配列に変換して戻す。
実際のコードが、こちら。
Option Explicit Dim FSO As FileSystemObject Private Sub Class_Initialize() Set FSO = New FileSystemObject End Sub '[用 途] ' 指定フォルダ下にあるフォルダ名やファイル名を取得 '[引 数] ' folder_path As String 指定フォルダ ' return_group As ReturnGroup 取得対象(フォルダ or ファイル) ※初期値:フォルダ ' return_type As ReturnType 格納方法(配列 or コレクション) ※初期値:配列 '[戻り値] ' 「フォルダまたはファイル」名称を格納した「配列またはコレクション」 '[備 考] ' 標準モジュールの列挙型(ReturnGroup および ReturnType)とセットで使用 Public Function GetFolderFileNames(folder_path As String, _ Optional return_group As ReturnGroup = myVbFolder, _ Optional return_type As ReturnType = myVbSeq) As Variant Dim TempCol As Collection Set TempCol = New Collection On Error GoTo er ' 名称取得。 Select Case return_group 'フォルダの場合。 Case myVbFolder Dim myFolder As Folder For Each myFolder In FSO.GetFolder(folder_path).SubFolders TempCol.Add myFolder.Name Next ' ファイルの場合。 Case myVbFile Dim myFile As File For Each myFile In FSO.GetFolder(folder_path).Files TempCol.Add myFile.Name Next End Select ' 格納方法。 Select Case return_type ' 配列の場合。 Case myVbSeq GetFolderFileNames = ToArray(TempCol) ' コレクションの場合。 Case myVbCol Set GetFolderFileNames = TempCol End Select Exit Function er: GetFolderFileNames = Array() End Function
ユーザーフォーム側は、関数の名前を変えるぐらいで、ほとんど差は無いので割愛する。一応正常に動作したので、良しとしよう。
でも、まだまだ簡略化できそうだ。これについては、明日改めて挑戦します。
参考まで。