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

該当するファイルを探すという行為をフォルダを見つけるたびに1階層下に移動し繰り返しているだけですよね。
こういったパターンの時に使えますね。
他の例だと、クイックソートとかも使いどころですよね。
まずは、再帰処理を使う必要がないくらい単純な例を使って実際に使ってみましょう。
では、10カウントダウンする関数を考えてみます。
普通に書くと、以下のように書けば実現できます。
これと同様のことを再帰処理で実現すると…
再帰処理といえば、ある一定の処理が繰り返し
樹木の枝のように発生する場合に使う処理ですね。
例えば、サブフォルダ内のファイルを検索する場合

該当するファイルを探すという行為をフォルダを見つけるたびに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
シンプルですねぇ。
これは、カウントするという行為を10回繰り返していて
値だけが変わっているということに着目して書き換えたものです。
ただ、fot文で簡単にかけちゃうといまいち再帰処理のメリットを感じませんね
そんなわけで、実際にサブフォルダ内のファイルを探すプログラムあたりを
書いてみると再帰処理のよさを感じられると思うので実際に書いてみるとよいと思います。
参考までに、自分が作成した関数を掲載しておきます。
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 件のコメント:
コメントを投稿