CSVファイルや、システムが出力したログファイルなど、外部のテキストファイル(.txt
)の内容をExcelに読み込んでデータとして活用したい、という場面は非常に多くあります。
FileSystemObject (FSO)
を使えば、テキストファイルを開いて、その内容をVBAで簡単に読み取ることができます。読み込み方法には、主に**ファイル全体を一度に読み込む.ReadAll
**と、**1行ずつ読み込む.ReadLine
**の2つのアプローチがあります。
この記事では、両方の方法をコード例と共に解説します。
【準備】参照設定
FSOを快適に利用するため、VBAエディタでツール
> 参照設定
を開き、**「Microsoft Scripting Runtime」**にチェックを入れておくことを推奨します。
方法1:ファイル全体を一度に読み込む (.ReadAll
)
ファイルの内容をすべて一度に、一つの巨大な文字列として読み込む方法です。コードがシンプルになるため、比較的小さなファイル(数MB程度まで)を扱う場合に適しています。
完成したVBAコード
'参照設定: Microsoft Scripting Runtime
Sub ReadTextFile_AllAtOnce()
' 変数を宣言します
Dim fso As New FileSystemObject
Dim ts As TextStream
Dim filePath As String
Dim fileContent As String
Dim linesArray As Variant
Dim i As Long
' 読み込みたいテキストファイルのパス
filePath = ThisWorkbook.Path & "\SampleData.txt"
If Not fso.FileExists(filePath) Then
MsgBox "指定されたファイルが見つかりません。", vbCritical
Exit Sub
End If
'--- 1. 読み取りモードでファイルを開く ---
Set ts = fso.OpenTextFile(filePath, ForReading)
'--- 2. .ReadAllで全内容を一度に読み込む ---
fileContent = ts.ReadAll
'--- 3. ファイルを閉じる ---
ts.Close
'--- 4. 読み込んだ内容を改行コードで分割し、配列に格納 ---
linesArray = Split(fileContent, vbCrLf)
'--- 5. 配列の内容をセルに書き出す ---
For i = 0 To UBound(linesArray)
ActiveSheet.Cells(i + 1, "A").Value = linesArray(i)
Next i
MsgBox "ファイルの読み込みと展開が完了しました。"
End Sub
コードのポイント解説
fso.OpenTextFile(filePath, ForReading)
: ファイルを「読み取り専用(ForReading
)」モードで開きます。ts.ReadAll
:TextStream
オブジェクト(ts
)のReadAll
メソッドが、ファイルの内容を最初から最後まで、すべて連結した一つの文字列として返します。Split(fileContent, vbCrLf)
: 取得した巨大な文字列を、改行コード(vbCrLf
)を区切り文字としてSplit
関数で分割し、各行を要素とする配列に変換しています。
方法2:1行ずつループで読み込む (.ReadLine
)
巨大なファイル(数GBなど)を扱う場合、.ReadAll
ではメモリを大量に消費してしまう可能性があります。そのような場合は、.ReadLine
メソッドを使って1行ずつ読み込む方が、メモリに優しく安定した処理になります。
完成したVBAコード
'参照設定: Microsoft Scripting Runtime
Sub ReadTextFile_LineByLine()
Dim fso As New FileSystemObject
Dim ts As TextStream
Dim filePath As String
Dim lineBuffer As String
Dim rowCounter As Long
filePath = ThisWorkbook.Path & "\SampleData.txt"
If Not fso.FileExists(filePath) Then Exit Sub
Set ts = fso.OpenTextFile(filePath, ForReading)
rowCounter = 1
'--- ファイルの終端(AtEndOfStream)に達するまでループ ---
Do Until ts.AtEndOfStream
' .ReadLineで1行だけ読み込む
lineBuffer = ts.ReadLine
' 読み込んだ行をセルに書き出す
ActiveSheet.Cells(rowCounter, "C").Value = lineBuffer
rowCounter = rowCounter + 1
Loop
ts.Close
MsgBox "1行ずつの読み込みが完了しました。"
End Sub
コードのポイント解説
Do Until ts.AtEndOfStream
:TextStream
の.AtEndOfStream
プロパティは、ファイルの終端に達するとTrue
を返します。これを利用して、「ファイルの最後まで」という条件のDo...Loop
を作成します。ts.ReadLine
: ファイルから1行だけを読み込み、ファイルポインタを次の行の先頭に進めます。ループでこれを繰り返すことで、ファイルを1行ずつ処理できます。
まとめ
メソッド | 動作 | 長所 | 短所/適した場面 |
.ReadAll | ファイル全体を一度に読み込む | コードが簡潔。一般的なテキストファイルに最適。 | 巨大なファイルだとメモリを大量に消費する可能性がある。 |
.ReadLine | 1行ずつ読み込む | メモリ消費が少ない。GB単位の巨大なファイルでも安定。 | ループ処理が必要で、コードがやや長くなる。 |
結論として、一般的なサイズのテキストファイルを扱うのであれば、.ReadAll
とSplit
を組み合わせる方法が手軽で便利です。扱うファイルが非常に大きいと分かっている場合のみ、.ReadLine
を使ったループ処理を検討すると良いでしょう。