make is.dev make it simple. development.
2024年11月29日

フォルダ操作

EXCEL VBAでのフォルダ操作で、よく使うものチートシート。

いくつかで、
・通常のステートメントで実行するもの
・FileSystemObjectを使って実行するもの
の両方を載せておく。

使用環境

・Windows11
・EXCEL 2019

存在確認

Dim folderPath As String
folderPath = "[フォルダパス]"

If Dir(folderPath, vbDirectory) <> "" Then
    Debug.Print "フォルダが存在している"
End If
VBA

Dir()はフォルダが存在する場合はフォルダ名が返り、存在しない場合は空文字が返る。
手軽にやるならこれで事足りるが、何をやっているのか分かりづらくはあるので、丁寧にやるならFileSystemObjectを使った方が良い。

FileSystemObjectを使う場合は以下。

Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")

Dim folderPath As String
folderPath = "[フォルダパス]"

If fso.FolderExists(folderPath) Then
    Debug.Print "フォルダが存在している"
End If
VBA

「Microsoft Scripting Runtime」を参照設定している場合、以下でも良い。

Dim fso As FileSystemObject
Set fso = New FileSystemObject

Dim folderPath As String
folderPath = "[フォルダパス]"

If fso.FolderExists(folderPath) Then
    Debug.Print "フォルダが存在している"
End If
VB

FolderExists()はファイルが存在する場合はtrue、存在しない場合はfalseが返る。

作成

MkDir "[作成するフォルダパス]"
VBA

返り値はなく、失敗時はエラーが発生する。
複数階層のフォルダをまとめて作成は出来ない。

FileSystemObjectを使う場合は以下。

Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")

fso.CreateFolder "[作成するフォルダパス]"
VBA

返り値と失敗時の扱いはMkDirと同様。

移動、フォルダ名変更

Name "[移動元フォルダパス]" as "[移動先フォルダパス]"
VBA

返り値はなく、失敗時はエラーが発生する。
移動先フォルダが既に存在している場合、上書きされずにエラーになる。

場所の変更以外に、フォルダ名も同様に変更できる。

FileSystemObjectを使う場合は以下。

Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")

fso.MoveFolder "[移動元フォルダパス]", "[移動先フォルダパス]"
VBA

返り値と失敗時の扱いや、フォルダが既に存在している場合の扱いはNameと同様。

複製(コピー)

FileSystemObjectを使う。

Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")

fso.CopyFolder "[コピー元フォルダパス]", "[コピー先フォルダパス]", True
VBA

返り値はなく、失敗時はエラーが発生する。

第三引数のTrue/Falseで、上書きを許可するか指定出来る。
省略可能で既定値はTrue=上書き可。

削除

RmDir "[削除するファイルパス]"
VBA

返り値はなく、失敗時はエラーが発生する。
中にファイルやフォルダがあると削除出来ないので、下の階層から消す必要がある。

FileSystemObjectを使う場合は以下。

Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")

fso.DeleteFolder "[削除するファイルパス]", False
VBA

返り値と失敗時の扱いはRmDirと同様。
ただこちらは、中にファイルがあってもまとめて消せる。

第二引数のTrue/Falseで、読み取り専用ファイルの削除を許可するか指定出来る。
この指定は、フォルダではなくフォルダに含まれるファイルが読み取り専用かどうか、に作用する。
つまり、フォルダ自体はここの指定や読み取り専用かどうかに関わらず消える。
中のファイルも、エラーになった場合も消せるものは消してしまうので注意が必要。
省略可能で既定値はFalse=削除不可。

エクスプローラーで開く

Dim folderPath As String
folderPath = "[開くフォルダパス]"

Shell "C:\windows\explorer.exe " & folderPath, vbNormalFocus
VBA

中のファイルリストを取得する

Dim fileName As String
fileName = Dir("[開くフォルダパス]" & "\")

Do While fileName <> ""
    Debug.Print fileName
    fileName = Dir()
Loop
VBA

Dirを使って含まれるファイル名を順次取得する。
フォルダパスの指定の際、末尾に「\」が必要なので注意。

これだけだとフォルダ名は除かれるが、Dirの第二引数にvbDirectoryを指定すればフォルダ名も含めて取得出来る。
ただし、「.」「..」も拾われるので注意。

以下のように、ワイルドカードを使ってフィルタをかけることも出来る。

Dim fileName As String
fileName = Dir("[開くフォルダパス]" & "\*.xlsx")

Do While fileName <> ""
    Debug.Print fileName
    fileName = Dir()
Loop
VBA

FileSystemObjectを使う場合は以下。

Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")

Dim folder As Object
Set folder = fso.GetFolder("[開くフォルダパス]")

' ファイルリスト
Dim file As Object
For Each file In folder.Files
    Debug.Print file.name
Next

' フォルダリスト
Dim subFolder As Object
For Each subFolder In folder.SubFolders
    Debug.Print subFolder.name
Next
VBA

こちらの場合はファイルとフォルダは別の取得になる。
また、フォルダリストに「.」「..」は入ってこない。

Dirのようにフィルタをかけることは出来ないが、以下のように拡張子を拾う等すれば似たようなことは出来る。

Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")

Dim folder As Object
Set folder = fso.GetFolder("[開くフォルダパス]")

' ファイルリスト
Dim file As Object
For Each file In folder.Files
    If fso.GetExtensionName(file.name) = "xlsx" Then
        Debug.Print file.name
    End If
Next
VB