0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

📊連載第11回!初心者のためのExcel VBA入門:FileSystemObjectでフォルダ管理を簡単マスター💼

Posted at

Excel VBAにおけるFileSystemObjectを活用した高度なファイル操作

私はVBAの活用経験を通じて得た知識を整理し、共有する目的で記事を作成しているプログラミング歴1年半になるエンジニアです。前回は、FileSystemObjectの基本と設定方法について解説しました。今回は、FileSystemObject(FSO)を活用した高度なファイル操作について詳しく説明します。FSOを使いこなすことで、より効率的なファイル管理が可能になり、実務における業務効率を大幅に向上させることができます。

目次

はじめに

Excel VBAでファイル操作をさらに強化するためには、FileSystemObject(FSO)の活用が鍵となります。FSOは、ファイルやフォルダを効率的に操作するためのさまざまなメソッドを提供しており、複雑なファイル管理タスクを簡略化することができます。

FileSystemObjectの主要メソッド

FileSystemObject を使用すると、VBA内でフォルダの作成、削除、移動、コピーといった操作を簡単に行うことができます。 これらの操作は、データの整理やバックアップ、一時フォルダの作成など、様々な場面で役立ちます。

メソッド名 説明
CreateFolder 新しいフォルダを作成することができます。
DeleteFolder 指定したフォルダを削除することができます。削除する際は、元に戻せないため注意が必要です。
MoveFolder 指定したフォルダを別の場所へ移動することができます。
CopyFolder 指定したフォルダを別の場所へコピーすることができます。
FolderExists 指定したフォルダが存在するかどうかを確認することができます。
GetFile 指定したファイルのオブジェクトを取得し、そのファイル情報(サイズ、作成日時など)を参照することができます。
GetFolder 指定したフォルダのオブジェクトを取得し、そのフォルダ情報(サイズ、作成日時など)を参照することができます。

フォルダの作成

新しいフォルダを作成するには、FileSystemObjectCreateFolder メソッドを使用してます。

' フォルダを作成する(Early Binding)
Sub CreateNewFolder()
    ' FileSystemObjectの変数
    Dim fso As New FileSystemObject
    
    ' 作成するフォルダのパス
    Dim folderPath As String
    
    ' フォルダのパスを設定。(ドキュメントフォルダ内に"NewFolder"という名前で作成)
    folderPath = Environ("USERPROFILE") & "\Documents\NewFolder"
    
    ' フォルダが既に存在しないか確認
    If Not fso.FolderExists(folderPath) Then
        ' フォルダを作成
        fso.CreateFolder folderPath
        ' 作成成功のメッセージを表示
        MsgBox "フォルダ '" & folderPath & "' を作成しました。", vbInformation
    Else
        ' フォルダが既に存在する場合のメッセージを表示
        MsgBox "フォルダ '" & folderPath & "' は既に存在します。", vbExclamation
    End If
End Sub

Environ関数について

Environ関数は、VBAでシステム環境変数の値を取得するための組み込み関数です。この関数を使用すると、ユーザーのホームディレクトリやシステムフォルダなど、Windows環境で定義されている環境変数の値を簡単に取得できます。

よく使われる環境変数

環境変数名 説明 一般的な値の例
USERNAME 現在ログインしているユーザー名 ユーザー名
USERPROFILE 現在のユーザーのフォルダ C:\Users\ユーザー名
COMPUTERNAME コンピュータの名前 PC名
TEMP 一時ファイル用フォルダ C:\Users\ユーザー名\AppData\Local\Temp
APPDATA よく使うアプリの設定などが保存されるフォルダ C:\Users\ユーザー名\AppData\Roaming

フォルダの削除

既存のフォルダを削除するには、FileSystemObjectDeleteFolder メソッドを使用します。

' フォルダを削除する(Early Binding)
Sub DeleteExistingFolder()
     ' FileSystemObjectの変数
    Dim fso As New FileSystemObject
    
    ' 削除するフォルダのパス
    Dim folderPath As String
    
    ' 削除するフォルダのパスを設定
    folderPath = Environ("USERPROFILE") & "\Documents\NewFolder"
    
    ' フォルダが存在するか確認
    If fso.FolderExists(folderPath) Then
        ' フォルダを削除(第2引数にTrueを指定すると、読み取り専用フォルダも強制的に削除)
        fso.DeleteFolder folderPath, False ' False:読み取り専用属性のフォルダは削除しない
        ' 削除成功のメッセージを表示
        MsgBox "フォルダ '" & folderPath & "' を削除しました。", vbInformation
    Else
        ' フォルダが存在しない場合のメッセージを表示
        MsgBox "フォルダ '" & folderPath & "' は存在しません。", vbExclamation
    End If
End Sub

DeleteFolderメソッドの使用時の注意点

  • 削除されたフォルダとその中身はゴミ箱に移動されず、完全に削除されます
  • 第2引数のForceパラメータをTrueに設定すると、読み取り専用ファイルも含めて強制的に削除します
  • 重要なデータを誤って削除しないよう、削除前に確認メッセージを表示することを強く推奨します
  • フォルダ内にファイルがある場合、それらも全て削除されるため、特に注意が必要です
  • 本番環境で使用する前に、必ずテスト環境で動作確認を行ってください

フォルダの移動

フォルダを別の場所に移動するには、FileSystemObjectMoveFolder メソッドを使用します。

' フォルダを移動する(Early Binding)
Sub MoveExistingFolder()
     ' FileSystemObjectの変数
    Dim fso As New FileSystemObject
    
    ' 移動するフォルダのパス
    Dim sourceFolderPath As String
    
    ' 移動先のフォルダのパス
    Dim destinationFolderPath As String
    
    ' 移動元のフォルダパスを設定
    sourceFolderPath = Environ("USERPROFILE") & "\Documents\NewFolder"
    
    ' 移動先のフォルダパスを設定。(ドキュメントフォルダに"Backup"という名前のフォルダを作成し、移動)
    destinationFolderPath = Environ("USERPROFILE") & "\Documents\Backup"
    
    ' 移動元のフォルダが存在するか確認
    If fso.FolderExists(sourceFolderPath) Then
        ' 移動先のフォルダが存在しない場合は作成
        If Not fso.FolderExists(destinationFolderPath) Then
            fso.CreateFolder destinationFolderPath
        End If
        
        ' フォルダを移動
        fso.MoveFolder sourceFolderPath, destinationFolderPath
        ' 移動成功のメッセージを表示
        MsgBox "フォルダ '" & sourceFolderPath & "' を '" & destinationFolderPath & "' に移動しました。", vbInformation
    Else
        ' 移動元のフォルダが存在しない場合のメッセージを表示
        MsgBox "フォルダ '" & sourceFolderPath & "' は存在しません。", vbExclamation
    End If
End Sub

フォルダのコピー

フォルダを別の場所にコピーするには、FileSystemObjectCopyFolder メソッドを使用します。

' フォルダをコピーする(Early Binding)
Sub CopyExistingFolder()
    ' FileSystemObjectの変数
    Dim fso As New FileSystemObject
    
    ' コピー元のフォルダのパス
    Dim sourceFolderPath As String
    
    ' コピー先のフォルダのパス
    Dim destinationFolderPath As String
    
    ' コピー元のフォルダパスを設定
    sourceFolderPath = Environ("USERPROFILE") & "\Documents\NewFolder"
    
    ' コピー先のフォルダパスを設定
    destinationFolderPath = Environ("USERPROFILE") & "\Documents\Backup"
    
    ' コピー元のフォルダが存在するか確認
    If fso.FolderExists(sourceFolderPath) Then
        ' コピー先のフォルダが存在しない場合は作成
        If Not fso.FolderExists(destinationFolderPath) Then
            fso.CreateFolder destinationFolderPath
        End If
        
        ' フォルダをコピー
        fso.CopyFolder sourceFolderPath, destinationFolderPath
        ' コピー成功のメッセージを表示
        MsgBox "フォルダ '" & sourceFolderPath & "' を '" & destinationFolderPath & "' にコピーしました。", vbInformation
    Else
        ' コピー元のフォルダが存在しない場合のメッセージを表示
        MsgBox "フォルダ '" & sourceFolderPath & "' は存在しません。", vbExclamation
    End If
End Sub

MoveFolderCopyFolder メソッドは、移動先またはコピー先に同名のフォルダが存在する場合、エラーが発生します。
エラーを避けるためには、移動またはコピー先のフォルダ名を変更するか、事前に同名フォルダの存在を確認する必要があります。

フォルダ内のファイル一覧取得

FileSystemObjectを使用すると、特定のフォルダ内のファイル一覧を取得することもできます。FolderオブジェクトのFilesプロパティを使用すると、フォルダ内のすべてのファイルを取得できます。

基本的な使い方

' フォルダ内のファイル一覧を取得する(Early Binding)
Sub GetFileListEarlyBinding()
    ' 変数宣言
    Dim fso As New FileSystemObject
    Dim folderPath As String
    Dim folder As folder
    Dim file As file
    Dim fileList As String

    ' ファイル一覧を取得するフォルダパスを設定
    folderPath = Environ("USERPROFILE") & "\Documents"

    ' フォルダが存在するか確認
    If fso.FolderExists(folderPath) Then
        ' フォルダオブジェクトを取得
        Set folder = fso.GetFolder(folderPath)

        ' ファイル一覧を初期化
        fileList = ""

        ' フォルダ内のすべてのファイルに対してループ
        For Each file In folder.Files
            ' ファイル名をファイル一覧に追加
            fileList = fileList & file.Name & vbCrLf
        Next file

        ' ファイル一覧を表示
        MsgBox "ファイル一覧:" & vbCrLf & fileList, vbInformation
    Else
        ' フォルダが存在しない場合はメッセージを表示
        MsgBox "フォルダが見つかりません: " & folderPath, vbExclamation
    End If
End Sub

フォルダ内のファイル一覧を取得する処理は、特定の種類のファイルを一括処理する場合や、ファイル管理ツールを作成する場合に役立ちます。

Folderオブジェクトの主なプロパティとメソッド

プロパティ/メソッド 説明
Files フォルダ内のファイルコレクション
SubFolders フォルダ内のサブフォルダコレクション
Path フォルダの完全パス
Name フォルダ名
Size フォルダサイズ(バイト単位)
DateCreated フォルダの作成日時
DateLastModified フォルダの最終更新日時
DateLastAccessed フォルダの最終アクセス日時
IsRootFolder ルートフォルダかどうか

サブフォルダを含むファイル一覧の取得

サブフォルダを含めたすべてのファイルを一覧表示するには、再帰処理を使用します。
再帰処理は、自分自身を何度も呼び出すプログラムの書き方です。
この方法は、フォルダの中にさらにフォルダがあるような複雑な仕組みを持つデータを扱うときに特に役立ちます。

' サブフォルダを含むすべてのファイル一覧を取得する関数(Early Binding)
Sub ListAllFilesRecursively()
    ' 変数宣言
    Dim fso As New FileSystemObject
    Dim folderPath As Variant
    Dim rowNum As Long
    
    ' フォルダ選択ダイアログを表示
    With Application.FileDialog(msoFileDialogFolderPicker)
    
        ' ダイアログがキャンセルされたら処理を終了
        If .Show = False Then Exit Sub
        
        ' 選択されたフォルダのパスを取得
        folderPath = .SelectedItems(1)
    End With
    
    ' シートをクリアして見出しを設定
    With Worksheets("Sheet1")
        ' シートの内容をすべて消去
        .Cells.Clear

        ' 各列に見出しを設定
        .Cells(1, 1).Value = "ファイル名"
        .Cells(1, 2).Value = "更新日時"
        .Cells(1, 3).Value = "フォルダパス"
        
        ' 見出し行を太字に設定
        .Range("A1:C1").Font.Bold = True
    End With
    
    ' データの書き込みを2行目から開始
    rowNum = 2
    
    ' 再帰的にフォルダ内のファイルを取得
    Call ListFilesInFolderRecursive fso.GetFolder(folderPath), rowNum
    
    ' 列幅を内容に合わせて自動調整
    Worksheets("Sheet1").Columns("A:C").AutoFit
    
    ' 取得完了のメッセージを表示
    MsgBox "取得完了: " & (rowNum - 2) & "ファイル", vbInformation
End Sub

' 再帰的にフォルダ内のファイルを一覧表示するサブルーチン
Sub ListFilesInFolderRecursive(folder As Folder, ByRef rowNum As Long)
    ' ファイルオブジェクトの変数を宣言
    Dim file As File
    ' サブフォルダオブジェクトの変数を宣言
    Dim subFolder As Folder
    
    ' 現在のフォルダ内の各ファイルに対する処理
    For Each file In folder.Files
        ' Sheet1のセルにファイル情報を書き込む
        With Worksheets("Sheet1")
            ' ファイル名を1列目に書き込む
            .Cells(rowNum, 1).Value = file.Name
            ' 更新日時を2列目に書き込む
            .Cells(rowNum, 2).Value = file.DateLastModified
            ' フォルダパスを3列目に書き込む
            .Cells(rowNum, 3).Value = file.ParentFolder.Path
        End With
        ' 次の行に進む
        rowNum = rowNum + 1
    Next file
    
    ' 各サブフォルダに対して再帰的に処理を行う
    For Each subFolder In folder.SubFolders
        ' サブフォルダに対して同じ処理を再帰的に実行
        Call ListFilesInFolderRecursive subFolder, rowNum
    Next subFolder
End Sub

上記の例では、ListFilesInFolderRecursive サブルーチンがフォルダ内のファイルを処理した後、サブフォルダごとに自分自身を呼び出しています。これにより、どれだけ深い階層構造であっても、すべてのファイルを取得することができます。

Callステートメントについて

Call 他のプロシージャ(Subキーワードで始まる処理のブロック)を実行する際に使用します。 Call ListFilesInFolderRecursive fso.GetFolder(folderPath), rowNum のように記述することで、ListFilesInFolderRecursive サブルーチンに fso.GetFolder(folderPath)rowNum の値を引数として渡して実行します。 VBAでは Call を省略することも可能ですが、明示的に記述することでコードの可読性を高めることができます。

ファイルとフォルダの情報取得

ファイル情報の取得

FileSystemObjectを使用すると、ファイルの詳細な情報(サイズ、作成日時、更新日時など)を取得できます。

' ファイルの詳細情報を取得(Early Binding)
Sub GetFileInfo()
    ' 変数宣言
    Dim fso As New FileSystemObject
    Dim file As File
    Dim filePath As Variant
    Dim fileInfo As String
    
    ' ファイル選択ダイアログを表示
    filePath = Application.GetOpenFilename("すべてのファイル (*.*),*.*", , "ファイル情報を取得")
    
    ' キャンセルされた場合
    If filePath = False Then Exit Sub
    
    ' ファイルオブジェクトの取得
    Set file = fso.GetFile(filePath)
    
    ' ファイル情報の収集
    fileInfo = "ファイル名: " & file.Name & vbCrLf & _
               "ファイルパス: " & file.Path & vbCrLf & _
               "親フォルダ: " & file.ParentFolder.Path & vbCrLf & _
               "サイズ: " & file.Size & " バイト" & vbCrLf & _
               "作成日時: " & file.DateCreated & vbCrLf & _
               "最終更新日時: " & file.DateLastModified & vbCrLf & _
               "最終アクセス日時: " & file.DateLastAccessed & vbCrLf & _
               "種類: " & fso.GetFileType(file.Path) & vbCrLf & _
               "ショートパス: " & file.ShortPath & vbCrLf & _
               "ショート名: " & file.ShortName & vbCrLf & _
               "ドライブ: " & file.Drive.DriveLetter
    
    ' ファイル情報を表示
    MsgBox fileInfo, vbInformation, "ファイル情報"
End Sub

Fileオブジェクトの主なプロパティ

プロパティ 説明
Name ファイル名
Path ファイルの完全パス
ShortPath 8.3形式のファイルパス(Windows 95以前の古いシステムとの互換性のための短い名前形式)
ShortName 8.3形式のファイル名
Size ファイルサイズ(バイト単位)
DateCreated ファイルの作成日時
DateLastModified ファイルの最終更新日時
DateLastAccessed ファイルの最終アクセス日時
ParentFolder 親フォルダを示すFolderオブジェクト
Attributes ファイル属性(読み取り専用、隠しファイルなど)
Drive ファイルが格納されているドライブを示すDriveオブジェクト

Attributesプロパティについて

Attributes プロパティは、ファイルの属性(読み取り専用、隠しファイルなど)を表す数値です。
この属性を活用することで、ファイルが特定の状態にあるかどうかをチェックすることができます。

' ファイルの属性を取得して表示(Early Binding)
Sub GetFileAttributes()
    ' 変数宣言
    Dim fso As New FileSystemObject
    Dim filePath As Variant
    Dim fileAttributes As Integer
    Dim attributeInfo As String
    
    ' ファイル選択ダイアログを表示
    filePath = Application.GetOpenFilename("すべてのファイル (*.*),*.*", , "ファイル属性を取得")
    
    ' キャンセルされた場合
    If filePath = False Then Exit Sub
    
    ' ファイル属性を取得
    fileAttributes = fso.GetFile(filePath).Attributes
    
    ' 属性情報の生成
    attributeInfo = "ファイル属性:" & vbCrLf
    If (fileAttributes And 1) Then attributeInfo = attributeInfo & "読み取り専用" & vbCrLf
    If (fileAttributes And 2) Then attributeInfo = attributeInfo & "隠しファイル" & vbCrLf
    If (fileAttributes And 4) Then attributeInfo = attributeInfo & "システムファイル" & vbCrLf
    If (fileAttributes And 16) Then attributeInfo = attributeInfo & "ディレクトリ" & vbCrLf
    If (fileAttributes And 32) Then attributeInfo = attributeInfo & "アーカイブ" & vbCrLf
    
    ' 属性情報を表示
    MsgBox attributeInfo, vbInformation, "ファイル属性情報"
End Sub
主なファイル属性値
属性 説明
ReadOnly 1 読み取り専用ファイル
Hidden 2 隠しファイル
System 4 システムファイル
Directory 16 フォルダ
Archive 32 バックアップされていないファイル

複数の属性を設定する場合は、OR演算子 (Or) を使用して値を組み合わせます。属性を解除する場合は、AND演算子 (And) とNOT演算子 (Not) を組み合わせて使用します。

パス情報の操作

FileSystemObjectはパスの操作にも便利なメソッドを提供しています。

' パス情報を取得して操作(Early Binding)
Sub ManagePaths()
    ' 変数宣言
    Dim fso As New FileSystemObject
    Dim filePath As String
    Dim pathInfo As String
    
    ' サンプルファイルパス
    filePath = Environ("USERPROFILE") & "\Documents\レポート.xlsx"
    
    ' パス情報の収集
    pathInfo = "元のパス: " & filePath & vbCrLf & vbCrLf & _
               "ドライブ: " & fso.GetDriveName(filePath) & vbCrLf & _
               "親フォルダ: " & fso.GetParentFolderName(filePath) & vbCrLf & _
               "ファイル名: " & fso.GetFileName(filePath) & vbCrLf & _
               "ベース名: " & fso.GetBaseName(filePath) & vbCrLf & _
               "拡張子: " & fso.GetExtensionName(filePath) & vbCrLf & vbCrLf & _
               "パスの結合例: " & fso.BuildPath("C:\Projects", "新しいファイル.txt")
    
    ' パス情報を表示
    MsgBox pathInfo, vbInformation, "パス情報"
End Sub

FileSystemObjectが提供するパス操作用のメソッド

メソッド 説明
GetDriveName ドライブ名を取得 "C:"
GetParentFolderName 親フォルダのパスを取得 "C:\Projects\ExcelVBA\データ処理"
GetFileName ファイル名を取得(拡張子含む) "レポート.xlsx"
GetBaseName ファイル名を取得(拡張子なし) "レポート"
GetExtensionName 拡張子を取得(ドット除く) "xlsx"
BuildPath パスとファイル名を結合 fso.BuildPath("C:\Temp", "file.txt") = "C:\Temp\file.txt"
BuildPathの注意点

このメソッドはパスを結合する際に自動的に区切り文字(\)を挿入します。パスの最後に既に「\」がある場合でも重複して挿入されることはありません。

fso.BuildPath("C:\Temp\", "file.txt") = "C:\Temp\file.txt"  ' 正しく結合される
fso.BuildPath("C:\Temp", "\file.txt") = "C:\Temp\file.txt"  ' 「\」が重複しない

まとめ

FileSystemObject(FSO)は、Excel VBAでのファイル・フォルダ操作において非常に強力かつ柔軟なツールです。この記事で紹介したフォルダの作成、削除、移動、コピーなどの基本操作から、ファイル一覧の取得、サブフォルダを含む再帰的な処理、そしてファイル情報やパス情報の操作まで、これらのテクニックを習得することで業務の自動化効率を大幅に向上させることができます。

実務での活用においては、適切なエラー処理を組み込むことが非常に重要です。フォルダが存在しない、アクセス権がない、同名フォルダが既に存在するなど、様々な状況に対応できるよう、エラーハンドリングを考慮したコーディングを心がけてください。また、FileSystemObjectの提供する様々なメソッドやプロパティを理解し、目的に応じて適切に選択することで、より効率的な処理が可能になります。

これらのFileSystemObject技術を、以前に解説した配列や条件分岐、繰り返し処理などと組み合わせることで、より高度で実用的なExcel VBAアプリケーションを開発することができます。例えば、特定フォルダ内のすべてのExcelファイルを検索してデータを収集し、結果を新しいファイルに保存するといった複雑な処理も、今回紹介した技術を組み合わせることで実現可能です。

もし記事の内容で不明な点や、より詳しく知りたい部分がありましたら、コメントでお知らせください。また、実務でのFileSystemObjectの活用例や、より効率的な実装方法など、皆様のノウハウもぜひ共有していただければ幸いです。

次回の記事では、文字列操作に役立つStrConv関数について解説する予定です。StrConv関数は、全角・半角変換や大文字・小文字変換など、VBAにおける文字列処理を強力にサポートします。どうぞお楽しみに!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?