【VBA】FileSystemObject でフォルダパス操作

VBA

※この記事にはプロモーションが含まれています。

FileSystemObject とは何ですか?

FileSystemObject とは

 FileSystemObject (FSO) は、VBA(Visual Basic for Applications)でファイルやフォルダーの操作を簡単に行うためのオブジェクトです。このオブジェクトを使うことで、ファイルやフォルダーの作成、読み込み、コピー、移動、削除などをプログラム内で行うことができます。

  1. ファイル操作: ファイルの作成、削除、移動、コピー、読み書きが可能
  2. フォルダー操作: フォルダーの作成、削除、移動、コピー、一覧取得が可能
  3. パス操作: フルパス、ファイル名、拡張子などの情報を取得・操作
  4. ファイル/フォルダー情報取得: サイズ、作成日、更新日、アクセス日などのプロパティを取得

FileSystemObject を使用する際、参照設定をする方法と参照設定しない方法の二通りありますが、それぞれの利点を整理してみましょう。

参照設定とは何ですか?

参照設定とは

 参照設定とは、VBAでプログラムを作成する際に、特定の外部ライブラリやオブジェクトモデルを利用するための仕組みです。参照設定を行うことでVBAエディタはそのライブラリ内のオブジェクト、メソッド、およびプロパティを認識し、コード補完機能やオブジェクトブラウザを利用して詳細を確認できるようになって開発効率が上がります。

参照設定を行う場合(早期バインディング)の利点

  1. コード補完が有効:メソッドやプロパティが自動補完され、タイピングミスが減る。
  2. 型宣言ができるFileSystemObject を明示的に型宣言できてエラー検出がしやすい。
  3. 実行速度が速い:参照設定により遅延バインディングよりもパフォーマンスが向上する。
' FileSystemObjectのインスタンスを作成
    Dim fso As FileSystemObject
    Set fso = New FileSystemObject

参照設定を行わない場合(遅延バインディング)の利点

移植性とエラー回避
 CreateObject を使用する遅延バインディングでは、特定のライブラリへの参照設定が不要です。そのため、コードを別のPCや異なる環境に移しても参照設定を気にせずに実行できますので、対象のアプリケーション(例:ExcelやWord)がインストールされてさえいればバージョンが異なっていてもコードが動作します。

 また、ライブラリがインストールされていない環境でも参照設定のミスによるエラーを避けることができ、移植性が高く、エラーが起きにくいのが特徴です。

' FileSystemObjectのインスタンスを作成(遅延バインディング)
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")

 それぞれの利点に応じて開発環境や目的に合わせて使い分けると良いですが、基本的には参照設定をする方をお勧めします。

参照設定の仕方

1.Excelを開き、Alt + F11を押してVBAエディタを開きます。

2.VBAエディタのメニューバーから「ツール」を選択し、「参照設定」をクリックします。

「Microsoft Scripting Runtime」にチェックを入れ、「OK」を押します。

これで準備は完了です。次からは FileSystemObject の主な機能を紹介していきますね。

フォルダの操作

 FileSystemObject にはたくさんのメソッドやプロパティがあります。そのすべてを紹介するのは難しいので、よく使う主な機能に絞って紹介していきます。それ以外の詳細な情報を調べたい場合は次のVBAの公式リファレンスから確認することができます。➡ FileSystemObject

フォルダが存在するか確認する- FolderExists

  Dim fso As FileSystemObject
    Dim folderPath As String

    ' FileSystemObjectのインスタンスを作成
    Set fso = New FileSystemObject

    ' 確認するフォルダのパスを指定
    folderPath = "C:\TestFolder"

    ' フォルダが存在するかを確認
    If fso.FolderExists(folderPath) Then
        MsgBox "フォルダは存在します: " & folderPath
    Else
        MsgBox "フォルダは存在しません: " & folderPath
    End If

 早期バインディングを使う為に参照設定が必要です。FileSystemObject のインスタンスを作成する為に CreateObject を使わずにNewキーワードを使っています。

新しいフォルダを作成する- CreateFolder

' フォルダが存在しない場合、フォルダを作成
    If Not fso.FolderExists(folderPath) Then
        fso.CreateFolder folderPath
        MsgBox "フォルダを作成しました: " & folderPath
    Else
        MsgBox "フォルダは既に存在します: " & folderPath
    End If

 インスタンスを作成する部分とパスを指定するコードを省略しています。フォルダが存在するときのみ指定したフォルダを作成します。

フォルダのオブジェクトを取得する- GetFolder

 GetFolderメソッドは、FileSystemObjectを使用して指定されたパスにあるフォルダを取得し、そのフォルダに関するプロパティや操作を行うためのオブジェクトを返すメソッドです。このメソッドを使うことで、フォルダの名前、パス、サイズ、作成日などの情報にアクセスできるほか、フォルダ内のファイルやサブフォルダに対する操作も可能です。

' GetFolderを使用してフォルダオブジェクトを取得
Dim folder As Folder
Set folder = fso.GetFolder(folderPath)

' イミディエイトウィンドウにフォルダ情報を表示
    Debug.Print "フォルダ名: " & folder.Name
    Debug.Print "フォルダパス: " & folder.Path
    Debug.Print "作成日時: " & folder.DateCreated
    Debug.Print "サイズ (バイト): " & folder.Size
    Debug.Print "サブフォルダ数: " & folder.SubFolders.Count

サブフォルダへのアクセス- SubFolders

 SubFolders は指定されたフォルダ内のすべてのサブフォルダを含むコレクションを返します。

Dim folder As Folder
Dim subfolder As Folder

' GetFolderを使用してフォルダオブジェクトを取得
Set folder = fso.GetFolder(folderPath)

' サブフォルダを列挙
Debug.Print "ブログフォルダ:"
For Each subfolder In folder.SubFolders
    Debug.Print " - " & subfolder.Name
Next subfolder

フォルダを削除する- DeleteFolder

' 削除するフォルダのパスを指定
    folderPath = "C:\TestFolder"

    ' フォルダが存在する場合、フォルダを削除
    If fso.FolderExists(folderPath) Then
        fso.DeleteFolder folderPath
        MsgBox "フォルダを削除しました: " & folderPath
    Else
        MsgBox "フォルダは存在しません: " & folderPath
    End If

 VBAの FileSystemObject を使用して削除したフォルダやファイルは、ゴミ箱に移動することなく完全に削除されます。また、一度削除したデータを復元することはできませんので、このメソッドを使う際は注意して下さい。

ファイルを操作する

ファイルの作成、書き込み、ファイルを閉じる-CreteTextFile,WriteLine,Close

Dim fso As FileSystemObject
Dim ts As TextStream

Set fso = New FileSystemObject
Set ts = fso.CreateTextFile("C:\test.txt", True)
ts.WriteLine "Hello, World!"

' ファイルの処理が終わったら閉じる
ts.Close

 TextStream オブジェクトは、ファイルの内容を扱うための専用オブジェクトで、ファイルを読み込み、書き込み、また、ファイルを閉じる際に必要です。ただ、ファイル操作(コピー、削除、移動など)では TextStream は必要ありません。

 CreateTextFile の第二引数に True を設定すると指定したファイルが存在する場合はデータが新しい内容に上書きされます。ここを False にすると指定したファイルが存在する場合はエラーとなります。

 また、Close メソッドを使用することによって書き込んだデータが自動的に保存され、ファイルを正常に閉じることが出来ます。

ファイルを移動する- MoveFile

fso.MoveFile "C:\test.txt", "D:\test.txt"

 左側が移動する対象のファイルで右側が移動先になります。もし、移動先のファイル名を変えた場合は新しいファイル名に変更されます。

 移動先をフォルダに指定した場合はフォルダの中に格納します。

fso.MoveFile "C:\example.txt", "D:\backup\"

ファイルをコピーする- CopyFile

 移動とはファイルやフォルダを一箇所から別の場所へ完全に移しますが、コピーは元の場所にそのままファイルやフォルダを残し、新しい場所に同じものを作成します。

fso.CopyFile "C:\example.txt", "D:\example.txt"

オブジェクトの解放

 プログラムが動作中にオブジェクトを作成すると、そのオブジェクトはシステムのメモリやリソースを消費します。特に大規模なアプリケーションや長時間実行されるプログラムでは、使わなくなったオブジェクトを解放せずに残しておくとメモリの無駄遣いが積み重なり、メモリ不足や動作の遅延、最悪の場合はプログラムのクラッシュにつながる可能性があります。

 使用が終わったオブジェクトには Nothing を代入して明示的に解放することで、不要なメモリやシステムリソースの占有を防ぎましょう。

' オブジェクトを解放
    Set ts = Nothing
    Set fso = Nothing

ファイルの読み込み

 FileSystemObject を使用するとファイルシステム内のテキストファイルを読み込むことができますが、主にASCIIおよびUnicode (UTF-16) のエンコーディングに対応しており、UTF-8エンコーディングには直接対応していません。

 そのため、UTF-8のファイルを読み込もうとすると文字化けが発生してしまいます。UTF-8の内容を正しく読み込むためには、別の ADODB.Stream オブジェクトを使用する必要があります。

エンコードとは

 エンコードとは、データを特定の形に変えるプロセスで、特に文字データを扱うときにとても大切です。さまざまなエンコーディング方式がありそれぞれが異なるやり方で文字をコンピュータが理解できるバイナリデータに変換します。これによって、コンピュータは文字を正しく表示したり保存したりできるようになります。

ASCII(アスキー)

 最も基本的なエンコーディング方式で、英語のアルファベット(A-Z、a-z)、数字(0-9)、および一部の記号を含む合計128文字を扱います。このため、英語の文章を扱う際には十分ですが、他の言語には対応していません。

UTF-8

 世界中のさまざまな文字を扱うためのエンコーディング方式で、英語の文字は1バイトで表現されますが、他の言語の文字は2〜4バイトを使用します。これにより、日本語や中国語など多言語に対応しており、特にウェブサイトやアプリケーションで広く使われています。

UTF-16

 Unicodeに基づくエンコーディングで、主に2バイトで文字を表現しますが、場合によっては4バイトを使用することもあります。WindowsやJavaなどでよく見られるこの方式は文字数が多い場合にファイルサイズが大きくなることがあります。

ファイルの読み込み- ReadAll

'FileSystemObjectを宣言
Dim fso As FileSystemObject
Dim ts As TextStream
Dim filePath As String
Dim fileContent As String

' FileSystemObjectのインスタンスを作成
Set fso = New FileSystemObject

' 読み込みたいファイルのパスを指定
filePath = "C:\test.txt"

' ファイルが存在するか確認
If fso.FileExists(filePath) Then
    ' ファイルを開く(読み取り専用モード: ForReading = 1)
    Set ts = fso.OpenTextFile(filePath, ForReading)

    ' ファイルの内容を読み込む
    fileContent = ts.ReadAll

    ' イミディエイトウィンドウに出力
    Debug.Print fileContent

    ' テキストストリームを閉じる
    ts.Close
    Set ts = Nothing ' TextStreamオブジェクトを解放
Else
    Debug.Print "ファイルが見つかりません: " & filePath
End If

' FileSystemObjectを解放
Set fso = Nothing

 ReadAllはファイルの内容を一度にすべて読み込むためのメソッドですが、ファイルが非常に大きい場合は一度に全体をメモリに読み込むためパフォーマンスに影響が出る可能性があります。

 その場合はファイルから1行ずつデータを読み込む ReadLine メソッドを使用します。ファイルが長い場合や、行ごとにデータを処理したいときに役立ちます。

 例えば、特定の行だけを処理したい場合や、大きなファイルを効率的に扱いたい場合はこの方法が適しています。ReadLine を使用すれば、ファイル全体を読み込まず、逐次的に処理を進めることができるためメモリの負荷を抑えることができます。

 また、OpenTextFile は、FileSystemObject を使ってテキストファイルを開くメソッドです。このメソッドを使用すると、指定したファイルを読み取り、書き込み、または追加モードで開くことができます。

主なパラメーター

  • ファイル名: 開きたいファイルのパスを指定します。
  • モード: ファイルを開くモードを指定します。以下の値を使用します。
定数モード内容説明
1ForReading読み取り専用既存のファイルを読む
2ForWriting書き込み専用既存のファイルを上書きする
8ForAppending追加専用既存のファイルに追記す

 それ以外にも、Create は新しいファイルを作成するかどうかを指定、Delimiter はテキストファイル内のデータを区切るための文字を設定、Encoding はファイルのエンコーディング方式を指定など、これらのパラメーターを使うことでファイル操作をより柔軟に行うことが可能になります。

ファイルの読み込み- ReadLine

Dim line As String
' ファイルの最後まで行を読み込む
    Do While Not ts.AtEndOfStream
        line = ts.ReadLine
        Debug.Print line ' イミディエイトウィンドウに出力
    Loop

 AtEndOfStream は、ファイルやデータストリームを読み込む際にストリームの終端に到達したかどうかを判断するためのプロパティです。このプロパティは、ADODB.StreamFileSystemObjectTextStream オブジェクトでよく使用されます。

エンコードの変更におけるエラー対策?

 先程、FileSystemObjectではUTF-8は読み込めないと述べたのですが、事前に手動の設定やEncodingのパラメーターで変更して使えばよいのではという問題があります。

 もしエンコードの手動変換やパラメーター設定で変更したとして、例えば、UTF-8からASCIIに変換すると、ASCII範囲外の文字(日本語や特殊記号など)は削除されるか、異なる文字に置き換えられます。このため、そもそも変換後にファイルの重要な情報が失われるリスクがあるということになるわけです。

パスの操作の標準化

 パスの標準化とは、ファイルやフォルダのパスを一貫した形式に統一することです。これは、異なる環境やコード内で使われるパスが表現の違いによって誤動作やエラーを起こさないようにするために重要です。

 例えば、Windowsではバックスラッシュ(\)が使われ、LinuxやmacOSではスラッシュ(/)が使われます。また、絶対パスと相対パスの違いや、末尾にスラッシュが付くかどうかの違いも標準化によって整えることができます。標準化されたパスを使うことでコードの可読性が向上し、異なるシステム環境でも一貫して動作する安全性が確保されます。

 主な機能には相対パスを絶対パスに変換するGetAbsolutePathName、ディレクトリ区切り文字を統一するBuildPath、パス末尾のスラッシュを適切に処理するGetFolder、不要なスラッシュやパスセグメント(冗長な「.」や「..」など)を整理するGetParentFolderName、そしてパスの整合性をチェックするFileExistsFolderExistsなどがあります。

相対パスを絶対パスに変換する- GetAbsolutePathName

  ' FileSystemObjectの参照を作成
    Dim fso As FileSystemObject
    Set fso = New FileSystemObject

    ' 相対パスを指定(例: 現在のフォルダ内の "example.txt")
    Dim relativePath As String
    relativePath = "example.txt"
    
    ' カレントフォルダのパスを取得
    Dim currentFolder As String
    currentFolder = fso.GetAbsolutePathName(".") ' "."は現在のフォルダを意味する
    
    ' 相対パスを絶対パスに変換
    Dim absolutePath As String
    absolutePath = fso.GetAbsolutePathName(relativePath)
    
    ' 結果を表示
    MsgBox "絶対パス: " & absolutePath

    ' FileSystemObjectを解放
    Set fso = Nothing

 現在の作業フォルダが C:\Users\Example\Documents であり、相対パスが example.txt である場合、メッセージボックスには次のように表示されます。

絶対パス: C:\Users\Example\Documents\example.txt

パスを結合する- BuildPath

Dim fso As FileSystemObject
Set fso = New FileSystemObject

Dim folderPath As String
folderPath = "C:\Users\Example"

Dim fileName As String
fileName = "test.txt"

Dim fullPath As String
fullPath = fso.BuildPath(folderPath, fileName) ' C:\Users\Example\test.txt

MsgBox fullPath

BuildPathメソッドは、パスの結合時に「フォルダ名の末尾に\があるか」や「重複して\が挿入されていないか」などを自動的にチェックして処理してくれます。

パスを分解する- GetFileName,GetParentFolderName

Dim filePath As String
filePath = "C:\Users\Example\test.txt"

Dim fileName As String
fileName = fso.GetFileName(filePath) ' test.txt

Dim parentFolder As String
parentFolder = fso.GetParentFolderName(filePath) ' C:\Users\Example

MsgBox "File Name: " & fileName & vbCrLf & "Parent Folder: " & parentFolder

 GetFileName でファイル名の取得、GetParentFolderName で親フォルダ名を取得します。

おわりに

 FileSystemObject の主な機能についてご紹介しましたが、FileSystemObjectは、VBAを使用してファイルシステムを操作するための強力なツールとなります。

 また、ファイル操作などに関連して下記の記事でも便利な機能を紹介しておりますのでぜひ確認してみて下さい。

 最後までご覧頂きありがとうございました。

タイトルとURLをコピーしました