アドベントカレンダー 20日目
再帰処理といえば、ある一定の処理が繰り返し
樹木の枝のように発生する場合に使う処理ですね。
例えば、サブフォルダ内のファイルを検索する場合

該当するファイルを探すという行為をフォルダを見つけるたびに1階層下に移動し繰り返しているだけですよね。
こういったパターンの時に使えますね。
他の例だと、クイックソートとかも使いどころですよね。
まずは、再帰処理を使う必要がないくらい単純な例を使って実際に使ってみましょう。
では、10カウントダウンする関数を考えてみます。
普通に書くと、以下のように書けば実現できます。
これと同様のことを再帰処理で実現すると…
シンプルですねぇ。
これは、カウントするという行為を10回繰り返していて
値だけが変わっているということに着目して書き換えたものです。
ただ、fot文で簡単にかけちゃうといまいち再帰処理のメリットを感じませんね
そんなわけで、実際にサブフォルダ内のファイルを探すプログラムあたりを
書いてみると再帰処理のよさを感じられると思うので実際に書いてみるとよいと思います。
参考までに、自分が作成した関数を掲載しておきます。
再帰処理といえば、ある一定の処理が繰り返し
樹木の枝のように発生する場合に使う処理ですね。
例えば、サブフォルダ内のファイルを検索する場合

該当するファイルを探すという行為をフォルダを見つけるたびに1階層下に移動し繰り返しているだけですよね。
こういったパターンの時に使えますね。
他の例だと、クイックソートとかも使いどころですよね。
まずは、再帰処理を使う必要がないくらい単純な例を使って実際に使ってみましょう。
では、10カウントダウンする関数を考えてみます。
普通に書くと、以下のように書けば実現できます。
- Option Explicit
- Sub SampleCode()
- Call CountDown(10)
- End Sub
- Sub CountDown(ByVal num As Integer)
- Dim i As Integer
- For i = num To 1 Step -1
- Debug.Print i
- Next
- End Sub
これと同様のことを再帰処理で実現すると…
- Option Explicit
- Sub SampleCode()
- Call CountDown(10)
- End Sub
- Sub CountDown(ByVal num As Integer)
- Debug.Print num
- If 1 < num Then Call CountDown(num - 1)
- End Sub
- Option Explicit
- Function GetSubFolder(ByRef FilePaths As Object, ByVal CurrentFolder As String, Optional ByVal NameRule As String = "*")
- Dim FileName As String
- Dim Folder As Variant
- Dim Folders As Object
- Dim FSO As Object
- Dim TopFlag As Boolean
- '** Objectの生成 **
- Set FSO = CreateObject("Scripting.FileSystemObject")
- '存在しないパスのときは、関数を抜ける
- If Not FSO.FolderExists(CurrentFolder) Then Exit Function
- '該当するファイルの取得
- FileName = Dir(CurrentFolder & "\" & NameRule)
- Do While FileName <> ""
- FilePaths.Add CurrentFolder & "\" & FileName, FileName
- FileName = Dir()
- Loop
- 'サブフォルダの処理
- Set Folders = FSO.GetFolder(CurrentFolder)
- 'サブフォルダを一つずつループで処理する
- For Each Folder In Folders.SubFolders
- 'さらにその下の階層を調べる
- Call GetSubFolder(FilePaths, Folder.Path, NameRule)
- Next
- Set FSO = Nothing
- Set Folders = Nothing
- End Function
- '実際に使ってみる
- Sub SampleCode()
- Dim CurrentFolder As String
- Dim FilePath As Variant
- Dim FilePaths As Object
- '** Objectを生成 **
- Set FilePaths = CreateObject("Scripting.Dictionary")
- '引数
- '第一引数:見つかったパスを格納するDictionary
- ' Dictionaryはキーにフルパス、値にファイル名
- '第二引数:検索開始のフォルダパス
- '第三引数:Dir関数同様に探しだすファイル名をアスタリスクを使って指定。
- 'ファイルを探し出すフォルダパス
- CurrentFolder = "C:\Documents and Settings\Owner\My Documents\excel\test"
- '検索開始
- Call GetSubFolder(FilePaths, CurrentFolder, "*")
- '検索結果を出力
- For Each FilePath In FilePaths
- Debug.Print "フルパス:" & FilePath
- ' Debug.Print "ファイル:" & FilePaths.Item(FilePath)
- Next
- Set FilePaths = Nothing
- End Sub
0 件のコメント:
コメントを投稿