📊連載第10回！初心者のためのExcel VBA入門：FileSystemObjectでファイル操作を極める！📝

# Excel VBAでのFileSystemObject入門 - ファイル操作の基礎と設定方法

私はVBAの活用経験を通じて得た知識を整理し、共有する目的で記事を作成しているプログラミング歴1年半になるエンジニアです。前回は、Excel VBAにおけるファイル操作とフォルダ管理の基本について解説しました。今回は、その理解をさらに深め、より高機能で簡略化されたファイル操作が可能となる、FileSystemObject（FSO）の使い方を詳しく説明します。FSOを活用することで、日常的な業務の効率化につながるだけでなく、より洗練されたVBAアプリケーションの構築が可能となります。

- [第1回: Excel VBAの基礎知識とセキュリティ設定](https://qiita.com/CodeLeaf/items/2d3e3185a725480fecc3)
- [第2回: Excel VBAの基本操作とオブジェクトの理解](https://qiita.com/CodeLeaf/items/c65d2531908aaf53649d)
- [第3回: Excel VBAにおける変数と定数の基本](https://qiita.com/CodeLeaf/items/3b36eddf7b5a8b5c5d99)
- [第4回: Excel VBAにおけるシート操作の基本とエラー処理](https://qiita.com/CodeLeaf/items/573fb7c61a756aa123ea)
- [第5回: Excel VBAにおける条件分岐](https://qiita.com/CodeLeaf/items/8be52d682baa097a65c1)
- [第6回: Excel VBAにおける繰り返し処理の基本](https://qiita.com/CodeLeaf/items/5bc6c961a090e550bca9)
- [第7回: Excel VBAにおける配列とFor Eachの活用]()
- [第8回: Excel VBAにおけるFormulaとValueの使い分けとユーザー入力の取得](https://qiita.com/CodeLeaf/items/ecf312a53f7ede91bce9)
- [第9回: Excel VBAにおけるファイル操作とフォルダ管理の基本](https://qiita.com/CodeLeaf/items/e5520321e760364f6aae)
- 第10回: Excel VBAにおけるFileSystemObjectを活用した高度なファイル操作（本記事）
- [第11回: Excel VBAにおけるFileSystemObjectを活用した高度なファイル操作 応用編](https://qiita.com/CodeLeaf/items/4607db0151dddfb7f458)
- [第12回: Excel VBAにおけるStrConv関数の活用と応用テクニック](https://qiita.com/CodeLeaf/items/4f6358548bced6c047e0)
- [第13回: Excel VBAにおけるワークブックの安全な操作と管理テクニック](https://qiita.com/CodeLeaf/items/cf136898dd41c7dd5d9f)
- [第14回: Excel VBAにおけるFunction（関数）の作成と活用テクニック](https://qiita.com/CodeLeaf/items/a299f465bdcb1957e2be)
- [第15回: Excel VBAにおける配列を返す関数の作成と活用テクニック](https://qiita.com/CodeLeaf/items/711a93ac86b5c4150e13)
- [第16回: Excel VBAにおけるコレクションの活用と応用テクニック](https://qiita.com/CodeLeaf/items/6a28c65d5f8d19964664)
- [第17回: Excel VBAにおける辞書型（Dictionary）の活用と応用テクニック](https://qiita.com/CodeLeaf/items/5f85b2029e8d51eaa788)
- [第18回: Excel VBAにおけるEnum型を活用した関数設計と実装テクニック](https://qiita.com/CodeLeaf/items/3e91ef9556799d96aeea)
- [第19回: Excel VBAにおけるユーティリティ関数の作成と活用テクニック](https://qiita.com/CodeLeaf/items/bc156b6a9cadd7b10601)
- [第20回: Excel VBAにおける正規表現を活用したファイル名解析テクニック](https://qiita.com/CodeLeaf/items/86284498dee42aab731e)


## 目次

- [はじめに](#はじめに)
- [FileSystemObjectの準備と基本](#filesystemobjectの準備と基本)
- [ファイル操作の基本](#ファイル操作の基本)
- [テキストファイルの読み書き](#テキストファイルの読み書き)
- [まとめ](#まとめ)

## はじめに

Excel VBAでFileSystemObject（FSO）を活用することで、ファイル操作がより柔軟かつ強力になります。この記事では、FSOの基本的な概念から、ファイルの操作、テキストファイルの読み書きまで、具体的なコード例を交えながら解説します。FSOをマスターすることで、VBAを用いたファイル操作の幅が広がり、日々の業務をより効率的に自動化することができるでしょう。

## FileSystemObjectの準備と基本

### FileSystemObject（FSO）とは
    
FileSystemObject（FSO） とは、ファイルやフォルダといったファイルシステムを操作するための機能を提供するオブジェクトです。FSOを使用することで、VBAからファイルやフォルダの作成、削除、移動、コピー、属性の変更など、様々な操作を簡単に行うことができます。

FSOを利用する主なメリットは以下の通りです。

- **高度なファイル操作**
    ファイルの作成、削除、移動、コピーといった基本的な操作に加えて、ファイルの属性変更やテキストファイルの読み書きなど、より高度な操作が可能です
- **オブジェクト指向**
    ファイルやフォルダをオブジェクトとして扱うため、直感的で分かりやすいコードを書くことができます
- **クロスプラットフォーム**
    Windows環境であれば、異なるバージョンのOSでも動作するため、汎用性の高いコードを作成できます

### 使用方法

FSOは外部オブジェクト（VBAの標準機能ではなく、Windows OSが提供している別の機能）のため、利用には少し準備が必要です。使用方法には、`CreateObject` 関数を使う方法と、参照設定を行う方法の2種類があります。

#### CreateObject 関数を使用する方法:

`CreateObject`関数は、プログラム内で外部のオブジェクトを作成し、そのオブジェクトを操作する際に用いる関数です。

以下のように、まずオブジェクト変数を宣言し、インスタンス（オブジェクトの雛形から実際に作成された、使える状態の複製品）を作成します。

```vb
' FileSystemObjectのインスタンスを作成
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
```

:::note warn
#### 注意点

CreateObject関数を使用すると、インテリセンス（入力候補を表示する自動補完機能）が効かなくなります。
インテリセンスが効かなくなると、下記のようなデメリットが発生します。

- コーディング速度の低下
- タイポやシンタックスエラー（プログラムの文法ミス）の増加
- ドキュメント参照の増加（調べ物が増える）

そのため、**参照設定を行う方法を推奨**します。
:::


### 参照設定の追加

VBAエディタで `Microsoft Scripting Runtime` への参照設定を追加します。
この参照設定はブック（Excelファイル）ごとに設定する必要があります。

1. VBEエディタを開き、「ツール」→「参照設定」を選択
    　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818373/44abcb6d-07f0-45e6-80a9-9a6b4b495057.png)

2. 「Microsoft Scripting Runtime」をリストから探して、チェックを入れる
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818373/86b4301b-7775-43c0-9e85-5d167d16c789.png)

3. 「OK」をクリックして設定を完了

参照設定を追加すると、インテリセンスが有効になり、コーディングがしやすくなります。
また、`FSO` を直接定義できるようになります。
※ 下記のように１行で、簡単に記述できるようになります。

```vb
' FileSystemObjectのインスタンスを作成（参照設定を追加した場合の書き方）
Dim fso As New FileSystemObject
```

:::note info
**Early Binding vs Late Binding**

- **Early Binding（早期バインディング）**
    **参照設定**を追加する方法。
    - 型のチェックがコンパイル（プログラムを実行できる形式に変換すること）時に行われ、インテリセンスが利用できるため、コーディングが容易
    - 実行速度も向上

- **Late Binding（遅延バインディング）**
    参照設定を追加せず、**`CreateObject`** を使用する方法。
    - プログラムを実行するまで、プログラムが使うオブジェクトの種類が確定しません。そのため、コード配布時に、相手が参照設定をしていなくても動作する
    - ただし、インテリセンスは使えず、実行速度もやや低下

**Early Binding**で作成したExcelブックを配布する場合、参照設定はファイルに含まれるため、受け取った側が改めて参照設定を行う必要はありません。
:::

## ファイル操作の基本

### ファイルの存在確認

FileSystemObjectでファイルの存在を確認するには、`FileExists`メソッドを使用します。
※ フォルダの存在確認は `FolderExists` メソッドを使用します。使い方は同様です。

```vb
' ファイルの存在確認（Early Binding）
Sub CheckFileExists()
    ' 変数宣言
    Dim fso As New FileSystemObject
    Dim filePath As String
    
    ' パスの設定
    filePath = "C:\Data\example.xlsx"
    
    ' ファイルの存在確認
    If fso.FileExists(filePath) Then
        MsgBox "ファイルが存在します: " & filePath, vbInformation
    Else
        MsgBox "ファイルが存在しません: " & filePath, vbExclamation
    End If
End Sub
```

### ファイルの削除

ファイルを削除するには、`DeleteFile`メソッドを使用します。

```vb
' ファイルを削除する（Early Binding）
Sub DeleteFileExample()
    ' 変数宣言
    Dim fso As New FileSystemObject
    Dim filePath As String
    
    ' 削除するファイルパスを設定
    filePath = "C:\Data\sample.txt"
    
    ' ファイルが存在するか確認
    If fso.FileExists(filePath) Then
        ' ファイルを削除
        fso.DeleteFile filePath
        
        ' 削除完了のメッセージを表示
        MsgBox "ファイルを削除しました: " & filePath, vbInformation
    Else
        ' ファイルが存在しない場合はメッセージを表示
        MsgBox "削除するファイルが見つかりません: " & filePath, vbExclamation
    End If
End Sub
```

:::note warn
**DeleteFileメソッドの使用時の注意点**

- 削除されたファイルはゴミ箱に移動されず、完全に削除されます
- 重要なファイルを誤って削除しないよう、削除前に確認メッセージを表示することをお勧めします
- フォルダを削除する場合は別のメソッド（`DeleteFolder`）を使用する必要があります
:::

### ファイルのコピー

ファイルをコピーするには、`CopyFile`メソッドを使用します。

```vb
' ファイルをコピーする（Early Binding）
Sub CopyFileExample()
    ' 変数宣言
    Dim fso As New FileSystemObject
    Dim sourceFilePath As String
    Dim destinationFilePath As String
    
    ' コピー元とコピー先のファイルパスを設定
    sourceFilePath = "C:\Data\sample.txt"
    destinationFilePath = "C:\Backup\sample.txt"
    
    ' ファイルをコピー
    fso.CopyFile sourceFilePath, destinationFilePath
    
    ' コピー完了のメッセージを表示
    MsgBox "ファイルをコピーしました。" & vbCrLf & _
           "コピー元: " & sourceFilePath & vbCrLf & _
           "コピー先: " & destinationFilePath, vbInformation
End Sub
```

:::note warn
**ファイルコピー時の注意点**

- `CopyFile`メソッドの第3引数は、コピー先に同名のファイルが存在する場合に上書きするかどうかを指定します
- `True`の場合は上書き、`False`の場合は既存ファイルがあるとエラーが発生します
- デフォルトは`False`なので、上書きしたい場合は明示的に`True`を指定しましょう
:::

### ファイルの移動

ファイルを移動するには、`MoveFile`メソッドを使用します。

```vb
' ファイルを移動する（Early Binding）
Sub MoveFileExample()
    ' 変数宣言
    Dim fso As New FileSystemObject
    Dim sourceFilePath As String
    Dim destinationFilePath As String
    
    ' 移動元と移動先のファイルパスを設定
    sourceFilePath = "C:\Data\sample.txt"
    destinationFilePath = "C:\Archive\sample.txt"
    
    ' ファイルを移動
    fso.MoveFile sourceFilePath, destinationFilePath
    
    ' 移動完了のメッセージを表示
    MsgBox "ファイルを移動しました。" & vbCrLf & _
           "移動元: " & sourceFilePath & vbCrLf & _
           "移動先: " & destinationFilePath, vbInformation
End Sub
```

## テキストファイルの読み書き

FileSystemObjectの大きな利点の一つは、テキストファイルの読み書きが容易になることです。CSVファイルやログファイルなどのテキストベースのファイルを扱う場合に特に便利です。

### テキストファイルの作成と書き込み

テキストファイルを作成して書き込むには、CreateTextFileメソッドとTextStreamオブジェクトを使用します。

```vb
' テキストファイルを作成して書き込む（Early Binding）
Sub CreateAndWriteTextFile()
    ' 変数宣言
    Dim fso As New FileSystemObject
    Dim textFile As TextStream
    Dim filePath As String
    
    ' パスの設定
    filePath = "C:\Temp\出力データ.txt"
    
    ' テキストファイルを作成（引数: パス, 上書き, 文字コード）
    Set textFile = fso.CreateTextFile(filePath, True, False)
    
    ' ファイルに書き込み
    textFile.WriteLine "ExcelVBA データエクスポート"
    textFile.WriteLine "作成日時: " & Now()
    textFile.WriteLine "------------------------------"
    
    ' データの書き込み例（Excelシートのデータを出力）
    Dim i As Long
    For i = 1 To 5
        textFile.WriteLine "データ" & i & ": " & Cells(i, 1).Value
    Next i
    
    ' ファイルを閉じる
    textFile.Close
    
    ' 完了メッセージ
    MsgBox "テキストファイルを作成しました: " & filePath, vbInformation
End Sub
```

#### CreateTextFileメソッドの引数

| 引数       | 説明                                              |
|------------|---------------------------------------------------|
| filename   | 作成するファイルのパス                            |
| overwrite  | 既存ファイルを上書きするかどうか（True/False）    |
| unicode    | Unicodeで保存するかどうか（True/False）。Falseの場合はASCII形式で保存 |

#### TextStreamオブジェクトの主なメソッド

| メソッド           | 説明                                                           |
|--------------------|----------------------------------------------------------------|
| Write              | 改行なしで書き込み                                           |
| WriteLine          | 改行付きで書き込み                                            |
| WriteBlankLines    | 指定した数の空行を書き込み                                    |
| Close              | ファイルを閉じる（必ず実行する必要あり）                       |

:::note info 
#### Unicodeとエンコーディングについて

テキストファイルに文字を保存するとき、コンピュータは文字を数字に変換する必要があります。この数字と文字の対応表が「エンコーディング」です。Unicodeは、世界中の文字を統一的に扱えるように作られた、非常に大きな文字コード表です。

| 文字コード   | 説明                         | 特徴                                                         |
|--------------|------------------------------|--------------------------------------------------------------|
| ASCII        | 最も基本的な文字コード       | 英数字や基本記号のみ（128文字）をサポート。日本語不可。          |
| Shift-JIS    | 日本語Windowsでよく使われる  | 日本語に対応。Windows環境で一般的だが、他のOSとの互換性に問題あり。|
| UTF-8        | 現在の世界標準               | 英数字は1バイト、日本語などは2〜4バイトで表現。Webで最も広く使用。|
| UTF-16LE     | Windowsのアプリ内部で使用    | すべての文字を基本的に2バイト以上で表現。VBAのUnicodeオプションはこれを指す。|

:::

### テキストファイルの読み込み

テキストファイルの内容を読み込むには、`OpenTextFile` メソッドを使用します。

```vb
' テキストファイルを読み込む（Early Binding）
Sub ReadTextFile()
    ' 変数宣言
    Dim fso As New FileSystemObject
    Dim textFile As TextStream
    Dim filePath As String
    Dim fileContent As String
    Dim line As String
    Dim rowNum As Long
    
    ' パスの設定
    filePath = "C:\Temp\読み込みデータ.txt"
    
    ' テキストファイルを開く（引数: パス, モード, 作成, 文字コード）
    ' ForReading: 読み取り専用モード
    Set textFile = fso.OpenTextFile(filePath, ForReading, False)
    
    ' ファイルの内容を1行ずつ読み込み、Excelシートに出力
    rowNum = 1
    Do
        ' 1行読み込み
        line = textFile.ReadLine
        
        ' シートに出力
        Cells(rowNum, 1).Value = line
        rowNum = rowNum + 1
        
    ' ファイルの最後まで繰り返す
    Loop Until textFile.AtEndOfStream
    
    ' ファイルを閉じる
    textFile.Close
    
    ' 完了メッセージ
    MsgBox "テキストファイルを読み込みました: " & filePath & vbCrLf & _
           "行数: " & (rowNum - 1), vbInformation
End Sub
```

#### OpenTextFileメソッドの引数

| 引数     | 説明                                          |
|----------|-----------------------------------------------|
| filename | 開くファイルのパス                            |
| iomode   | **ファイルを開くモード**<br>　・ ForReading: 読み取り専用 (1)<br>　・ ForWriting: 書き込み用 (2)<br>　・ ForAppending: 追記用 (8)                          |
| create   | ファイルが存在しない場合に作成するか (True/False) |
| format   | **ファイルの形式を指定**<br>　・ TristateUseDefault: システムのデフォルト (-2)<br>　・ TristateTrue: Unicode (UTF-16LE) (-1)<br>　・ TristateFalse: ASCII (0)               |

#### TextStreamオブジェクトの主な読み込みメソッド

| メソッド       | 説明                                          |
|----------------|-----------------------------------------------|
| Read(count)    | 指定した文字数を読み込む                      |
| ReadLine       | 1行読み込む                                  |
| ReadAll        | ファイル全体を読み込む                        |
| AtEndOfStream  | ファイルの終端かどうかを判定するプロパティ    |

### 効率的なテキストファイル読み込み方法

テキストファイルが大きい場合、1行ずつ読み込む方法よりも、ファイル全体を一度に読み込んで処理する方が効率的です。

```vb
' テキストファイルを一括読み込みする効率的な方法（Early Binding）
Sub ReadTextFileEfficiently()
    ' 変数宣言
    Dim fso As New FileSystemObject
    Dim textFile As TextStream
    Dim filePath As String
    Dim entireContent As String
    Dim lines() As String
    Dim i As Long
    
    ' パスの設定
    filePath = "C:\Temp\読み込みデータ.txt"
    
    ' テキストファイルを開く
    Set textFile = fso.OpenTextFile(filePath, ForReading, False, TristateTrue) ' Unicodeで開く
    
    ' ファイルの内容を一度に全て読み込む
    entireContent = textFile.ReadAll
    
    ' ファイルを閉じる（読み込み後はすぐに閉じる）
    textFile.Close
    
    ' 読み込んだテキストを行ごとに分割
    lines = Split(entireContent, vbCrLf)
    
    ' 分割した行をシートに出力
    For i = LBound(lines) To UBound(lines)
        ' 空行でなければ出力
        If Trim(lines(i)) <> "" Then
            Cells(i + 1, 1).Value = lines(i)
        End If
    Next i
    
    ' 完了メッセージ
    MsgBox "テキストファイルを効率的に読み込みました: " & filePath & vbCrLf & _
           "行数: " & UBound(lines) - LBound(lines) + 1, vbInformation
End Sub
```

## まとめ

FileSystemObject（FSO）は、Excel VBAによるファイル操作において非常に強力かつ柔軟なツールです。この記事で紹介したFSOの基本設定から始まり、ファイルの存在確認、コピー、移動、削除といった基本操作、そしてテキストファイルの読み書きといった実用的な機能まで、これらを理解することで業務の自動化効率を大幅に向上させることができます。

実務では、適切な参照設定（Early BindingとLate Binding）を選択し、エラー処理を組み込むことで、より堅牢なアプリケーションを開発することが重要です。FileSystemObject技術を前回までに解説した条件分岐、繰り返し処理、配列などと組み合わせることで、より高度で実用的なExcel VBAアプリケーションを開発することができます。

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

次回の記事では、フォルダ操作やファイル情報の取得など、FSOを用いたより実践的なテクニックを解説する予定です。どうぞお楽しみに！