Top / プログラミングテクニック / 14.再帰的プログラミング

再帰的プログラミングとは

再帰的プログラミングは、あるサブルーチンが自分自身を呼び出すようなプログラミングです。
へたをうつと、無限ループに陥ってしまいますが、階層構造を表現するには、最適なプログラミングです。

それでは、ディレクトリ階層構造をたどって、リストボックスにファイルを列挙するような関数を作ってみましょう。

Dir関数は、再帰的な使用ができないため、あるディレクトリ下のファイルをいったん配列に格納し、その後、下の階層のディレクトリに移る必要があります。

ディレクトリファイルは、親へのポインタと、自分自身へのポインタをもっており、Dir関数は、それをも列挙してしまいます。名称は、それぞれ ”.”, “..” ですので、それを取り除く必要があります。

Dir関数の第2引数に、vbDirectoryを指定すると、ディレクトリと通常のファイルが列挙されます。
ディレクトリのみが列挙されるわけではありません。
ファイルがディレクトリかそうでないかを判別するには、GetAttr 関数を使います。
が、この関数は、排他のかかっているファイルを調べようとすると、エラーが発生してしまいます。
本来なら、ディレクトリ情報をAPIを使って調べるべきなのですが、エラーが起こったファイルは通常のファイルと判断することにします。

ファイルがディレクトリかどうか調べる関数を作っておきます。

Private Function IsDirectory(iCFName As String) As Boolean
    Dim pAttr As Long
    On Error Resume Next
    pAttr = GetAttr(iCFName)
    On Error GoTo 0
    If pAttr And vbDirectory Then
        IsDirectory = True
    End If
End Function

Dir関数でファイルを列挙する際、ディレクトリと通常のファイルが列挙されますので、配列に格納するには、ファイル名の配列と、そのファイルがディレクトリであるかどうかを示すフラグの配列が必要です。このように、同じインデックスで参照される配列は、構造体配列を使うべきです。

Private Type typFAttr
    Name As String
    IsDir As Boolean
End Type

コーディング例を示します。

' ディレクトリ下のファイルをリストボックスに列挙する関数
Public Sub EnumFiles(iList As ListBox, iDir As String)
Dim pPrmDir As String
Dim pFAttr() As typFAttr
Dim pFileCount As Long
Dim pFile As String
Dim pCFName As String
Dim i As Long

    ' ディレクトリ名に "\" を付加します
    If Right(iDir, 1) = "\" Then
        pPrmDir = iDir
    Else
        pPrmDir = iDir & "\"
    End If

    iList.AddItem pPrmDir                           'ディレクトリ自身をリストボックスに列挙します
    ReDim pFAttr(10)                                '配列の領域を確保します
    pFile = Dir(pPrmDir & "*", vbDirectory)
    Do Until pFile = ""
        If pFile <> "." And pFile <> ".." Then      '親と自分は除きます
            pCFName = pPrmDir & pFile               'ファイル完全名を取得
            pFileCount = pFileCount + 1
            If pFileCount > UBound(pFAttr) Then     '配列が足らなければ確保
                ReDim Preserve pFAttr(pFileCount + 10)
            End If
            With pFAttr(pFileCount)                 '情報を構造体配列に格納
                .Name = pCFName
                .IsDir = IsDirectory(pCFName)
            End With
        End If
        pFile = Dir() '次のファイル
    Loop

    For i = 1 To pFileCount
        With pFAttr(i)
            If .IsDir Then
               EnumFiles iList, .Name         'ディレクトリなら、再帰呼び出しをする
            Else
                iList.AddItem .Name
            End If
        End With
    Next

End Sub



トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   最終更新のRSS
Last-modified: 2009-10-25 (日) 23:55:55 (2800d)