【VBA】テキストファイルを読み書きする方法
更新日:2024/01/18
VBAでテキストファイルを読み書きする方法を紹介します。
- 1テキストファイルを開く
- 2Openステートメントでの読み書き
- 3Openステートメントの使用例
- 一行単位で読み込む:Line Input #
- 変数に値を読み込む:Input #
- 一行単位で書き込む:Print #
- 変数の値を書き込む: Write #
- 4FileSystemObject.OpenTextFileメソッド
- 5FileSystemObject.CreateTextFileメソッド
- 6File.OpenAsTextStreamメソッド
- 7Folder.CreateTextFileメソッド
- 8TextStreamオブジェクト
- メソッド
- プロパティ
- 9TextStreamオブジェクト使用例
- 一括読み込み例
- 文字数単位での読み込み例
- 1行単位での読み込み例
- 書き込み例
- 1行単位での書き込み例
テキストファイルを開く
テキストファイルを読み書きするには、最初にテキストファイルを開く必要があります。
テキストファイルを開く方法は、5つあります。
1のOpenステートメントVBAで完結している、つまりVBAで作成してVBAで読み込むテキストファイル向けです。
Openステートメントで開いたテキストファイルは、書き込み時にデータの型を判別するための加工を行ってから書き込みます。
読み込み時は、加工したデータを元のデータ型へ復元します。
そのため、テキストファイルの内容をそのまま読みとったり、文字列をそのまま書き込むことが難しい仕様となっています。
このような目的でファイルを読み書きするときは、2以降の方法で開きます。
なお現在はUTF-8ファイルでの読み書きが主流となっています。
UTF-8ファイルでの読み書きについては、次のページを読んでみてください。
Openステートメントでの読み書き
Openステートメントを使用すると、ファイルを開くことができます。
開く際にはファイルのパス名と、読み込み用か書き込み用かなどのモード、さらに開いた後にファイルを区別するための番号を指定します。
構文は次のようになっています。
Open pathname For mode [Access] [lock] As [#] filenumber [Len = reclength]
基本的には引数は、pathname、mode、filenumberを指定します。
- pathname: 開くファイルのパス
- mode: ファイルの使用目的。以下から選択
Append(追記用)、Binary(バイナリモード)、Input(入力用)、Output(書き込み用)、 Random(ランダムアクセス用) - access: 省略可能。許可される操作。以下から選択
Read(読み込み)、Write(書き込み)、Read Write(読み書き) - lock: 省略可能。他プロセスからのアクセス制限。以下から選択
Shared(許可)、Lock Read(読み込みを制限)、Lock Write(書き込みを制限)、Lock Read Write(読み書きを制限) - filenumber: 開いたファイルを識別する整数。ファイル番号。
通常は1~255までの数値。他アプリケーションから同時アクセスの可能性があるときは256~511 - reclength: 32,767以下の整数。
modeがRandom(ランダムアクセス)のとき、レコード長。
その他のとき、バッファサイズ。
テキストファイルの読み書きでは、modeはAppend(追記用)、Input(入力用)、Output(書き込み用)の3つから選択します。
filenumberは数値指定もできますが、FreeFile関数を使用することで未使用の番号を自動選択できます。
FreeFile [rangenumber]
戻り値はInteger型です。
rangenumberが0または省略された時、1~255までの数値を返します。
1が指定されると、256~511までの数値を返します。
ファイルを開いたら、読み書きを行います。
方法については、使用例を参考にしてください。
最後に、Closeステートメントでファイルを閉じます。
Close [filenumberlist]
filenumberlistは省略可能です。
省略すると、Openで開いている全てのファイルが閉じられます。
また、Close 1,2,3 のように複数のファイル番号を指定できます。
Openステートメントの使用例
Openステートメントの使用例を紹介します。
一行単位で読み込む:Line Input #
テキストファイルの内容を一行単位で読み込むときは、Inputモードでファイルを開き、Line Input #ステートメントで読み込みます。
Line Input #filenumber , varname
- filenumber: Openステートメントで指定したファイル番号です。
- varname: 改行文字を削除した文字列が格納されます。
※Line Input #ステートメントはPrint #ステートメントで書き込まれたファイルの読み込みを想定しています。
改行文字は、vbCr(&H0d)またはvbCrLf(&H0d0a)です。
vbLf(&H0a)は改行として扱われません。
Sub lineInputTest()
Const fileName As String = "C:\Users\xxx\Documents\text.txt"
Dim fileNumber As Integer
fileNumber = FreeFile
Open fileName For Input As #fileNumber
Dim LineText As String
Do Until EOF(fileNumber)
Line Input #fileNumber, LineText
Debug.Print LineText
Loop
Close #fileNumber
End Sub
EOF関数は、ファイルの現在位置が末尾にあるときTrueを返します。
そのためEOF関数がFalseを返す間、ループを繰り返しています。
変数に値を読み込む:Input #
Write #ステートメントで書き込んだテキストファイルの内容を変数に読み込むときは、Inputモードでファイルを開き、Input #ステートメントで読み込みますします。
Input #filenumber , varlist
- filenumber: Openステートメントで指定したファイル番号です。
- varlist: 変数をカンマ区切りで羅列
varlistは、Write #ステートメントで書き込んだ順番で変数の型を合わせます。
複数回に分けて読み込むこともできます。
Sub lineInputTest()
Const fileName As String = "C:\Users\xxx\Documents\text.txt"
Dim fileNumber As Integer
fileNumber = FreeFile
Open fileName For Input As #fileNumber
Dim txt As String, num As Integer, d As Date
Input #fileNumber, txt, num, d
Close #fileNumber
Debug.Print txt
Debug.Print num
Debug.Print d
End Sub
一行単位で書き込む:Print #
テキストファイルに一行単位で書き込むときは、Outputモードでファイルを開き、Print #ステートメントで書き込みます。
Print #filenumber , outputlist
- filenumber: Openステートメントで指定したファイル番号です。
- outputlist: 出力する値
各変数を ";" で区切って記述します。
数値等の非文字列データは文字列に変換されます。
Tab(n)とSpc(n)を記述できます。
Tab(n)は左端からn桁目の文字位置を表します。タブの個数ではありません。
Tab(n)で指定した位置が現在位置より前のときは、行替えが行われます。
Spc(n)はn個のスペース文字を表します。
※書き込まれたファイルを読み込むときは、Line Input #ステートメントを使用します。
Sub lineInputTest()
Const fileName As String = "C:\Users\xxx\Documents\text.txt"
Dim fileNumber As Integer
fileNumber = FreeFile
Open fileName For Output As #fileNumber
Dim txt As String, num As Integer, d As Date
txt = "こんにちは"
num = 1000
d = Date
Print #fileNumber, "123456789012345678901234567890"
Print #fileNumber, Tab(8); txt; Tab(20); num; Spc(4); d
Print #fileNumber, Tab(8); txt; Tab(8); num; Spc(4); d
Close #fileNumber
End Sub
上記のコードで作成されたファイルは、次のような内容になっています。
123456789012345678901234567890123456789012345678901234567890
こんにちは 1000 2023/12/18
こんにちは
1000 2023/12/18
変数の値を書き込む: Write #
ファイルの内容を変数に読み込むことを前提として変数の値をファイルに書き込むときは、Outputモードでファイルを開き、Write #ステートメントで書き込みます。
Write #filenumber , outputlist
- filenumber: Openステートメントで指定したファイル番号です。
- outputlist: 出力する値
各変数を "," で区切って記述します。
※文字列にダブルクォーテーションが含まれていると、Input #ステートメントでの読み込みが正常にできません
※書き込まれたファイルを読み込むときは、Input #ステートメントを使用します。
Sub lineInputTest()
Const fileName As String = "C:\Users\xxx\Documents\text.txt"
Dim fileNumber As Integer
fileNumber = FreeFile
Open fileName For Output As #fileNumber
Dim txt As String, num As Integer, d As Date
txt = "こんにちは"
num = 1000
d = Date
Write #fileNumber, txt, num, d
Close #fileNumber
End Sub
書き込まれたデータは型ごとに、元の型が判別できるような形式で書き込まれます。
上記のコードで作成されたファイルは、次のような内容になっています。
"こんにちは",1000,#2023-12-18#
文字列にダブルクォーテーションが含まれていると、次のようにダブルクォーテーションが二つ出力されます。
書き込む文字列: "こんにちは"A"さん"
ファイル内容: "こんにちは""A""さん"
Input #ステートメントで読み込むと3つの文字列として解釈されます。
FileSystemObject.OpenTextFileメソッド
OpenTextFileメソッドは、FileSystemObjectオブジェクトのメソッドです。
既存ファイルの読み込み、書き込み、追記を行うTextStreamオブジェクトを返しますが、ファイルが存在しないとき作成することもできます。
FileSystemObjectオブジェクト.OpenTextFile (FileName , [ IOMode ], [ Create ], [ Format ])
- FileName : ファイルのパス
- IOMode : 省略可能。ファイルのモードをIOMode列挙型で指定。規定値はForReading
■IOMode列挙型 定数 値 意味 ForAppendin 8 追記 ForReading 1 読み込み ForWriting 2 書き込み - Create : 省略可能。ファイルが存在しないとき作成するかどうか。規定値はFalse(作成しない)
- Format : 省略可能。ファイルの文字コードをTristate列挙型で指定。規定値はTristateFalse
■Tristate列挙型 定数 値 意味 TristateFalse 0 Ascii形式 TristateMixed -2 混在形式 TristateTrue -1 Unicode形式(UTF-16) TristateUseDefault -2 システムの既定の設定
formatのTristateMixedは意味合いがあいまいですが、TristateUseDefaultと同じ値なので、システムの既定の設定を使用すると解釈しておけばOKです。
またTristateFalseとTristateUseDefaultは、日本語環境ではシフトJISです。
次のコードはFileSystemObjectを取得後にテキストファイルを開き、内容を変数に読み込んでいます。
Sub openTextFileSample()
Const fileName As String = "C:\Users\xxxx\Documents\text.txt"
Dim fso As New Scripting.FileSystemObject
Dim stream As TextStream
Set stream = fso.OpenTextFile(fileName)
Dim textData As String
With stream
textData = .ReadAll
.Close
End With
Debug.Print textData
End Sub
読み込みはTextStreamオブジェクトで行っています。
TextStreamオブジェクトについては、このページのTextStreamオブジェクトを参照してください。
FileSystemObject.CreateTextFileメソッド
CreateTextFileメソッドは、FileSystemObjectオブジェクトのメソッドです。
ファイルを新規作成後に、TextStreamオブジェクトを返します。
FileSystemObjectオブジェクト.CreateTextFile(FileName , [ Overwrite ], [ Unicode ])
- FileName : ファイルのパス
- Overwrite : 省略可能。既存ファイルを上書きするかどうか。規定値はTrue(上書きする)
- Unicode : 省略可能。文字コードをUnicode(UTF-16)で開くかどうか。規定値はFalse(ASCIIで開く)
次のコードはFileSystemObjectを取得後にテキストファイル新規作成して、変数の内容をファイルに書き込んでいます。
Sub CreateTextFileSample()
Const fileName As String = "C:\Users\xxxx\Documents\text.txt"
Dim fso As New Scripting.FileSystemObject
Dim stream As TextStream
Set stream = fso.CreateTextFile(fileName)
Dim textData As String
textData = "書き込みテスト"
With stream
.Write textData
.Close
End With
End Sub
TextStreamオブジェクトについては、このページのTextStreamオブジェクトを参照してください。
File.OpenAsTextStreamメソッド
OpenAsTextStreamメソッドはFileSystemObjectのGetFileメソッドで取得されるFileオブジェクトのメソッドです。
OpenAsTextStreamメソッドを実行すると、Fileオブジェクトに関連付けられているファイルを開き、開いたファイルを操作するTextStreamオブジェクトを返します。
Fileオブジェクト.OpenAsTextStream( [ IOMode ], [ Format ] )
- IOMode : 省略可能。ファイルのモードをIOMode列挙型で指定。規定値はForReading
- Format : 省略可能。ファイルの文字コードをTristate列挙型で指定。規定値はTristateFalse
次のコードはFILEオブジェクトを取得後にテキストストリームを開き、内容を変数に読み込んでいます。
Sub openTextFileSample()
Const fileName As String = "C:\Users\xxxx\Documents\text.txt"
Dim fso As New Scripting.FileSystemObject
Dim fileObj As FILE
Set fileObj = fso.GetFile(fileName)
Dim stream As TextStream
Set stream = fileObj.OpenAsTextStream()
Dim textData As String
With stream
textData = .ReadAll
.Close
End With
Debug.Print textData
End Sub
TextStreamオブジェクトについては、このページのTextStreamオブジェクトを参照してください。
Folder.CreateTextFileメソッド
CreateTextFileメソッドはFileSystemObjectのGetFolderメソッドで取得されるFolderオブジェクトのメソッドです。
CreateTextFileメソッドを実行すると、Folderオブジェクトに関連付けられているフォルダ内に新規ファイルを作成してファイルを開き、開いたファイルを操作するTextStreamオブジェクトを返します。
Folderオブジェクト.CreateTextFile(FileName , [ Overwrite ], [ Unicode ])
- FileName : ファイルの名前
- Overwrite : 省略可能。既存ファイルを上書きするかどうか。規定値はTrue(上書きする)
- Unicode : 省略可能。文字コードをUnicode(UTF-16)で開くかどうか。規定値はFalse(ASCIIで開く)
次のコードはFolderオブジェクトを取得後にテキストファイル新規作成して、変数の内容をファイルに書き込んでいます。
Sub CreateTextFileSample()
Const folderName As String = "text.txt"
Const fileName As String = "C:\Users\xxxx\Documents\"
Dim fso As New Scripting.FileSystemObject
Dim folderObj As folder
Set folderObj = fso.GetFolder(folderName)
Dim stream As TextStream
Set stream = folderObj.CreateTextFile(fileName)
Dim textData As String
textData = "書き込みテスト2"
With stream
.Write textData
.Close
End With
End Sub
TextStreamオブジェクトについては、このページのTextStreamオブジェクトを参照してください。
TextStreamオブジェクト
TextStreamオブジェクトは、ファイルの読み書きを行うメソッドをメンバーに持つオブジェクトです。
FileSystemObjectオブジェクトのOpenTextFileメソッドとCreateTextFileメソッド、FileオブジェクトのOpenAsTextStreamメソッド、FolderオブジェクトのCreateTextFileメソッドで取得できます。
メソッド
TextStreamオブジェクトは、次のメソッドを持っています。
メソッド名 | 内容 | 使用例 |
---|---|---|
Close | TextStreamオブジェクトを閉じる | --- |
Read | 指定文字数を読み込む | 文字数単位での読み込み例 |
ReadAll | 全て読み込む | 一括読み込み例 |
ReadLine | 1行読み込む | 1行単位での読み込み例 |
Skip | 指定文字数を読み飛ばす | 文字数単位での読み込み例 |
SkipLine | 1行読み飛ばす | 1行単位での読み込み例 |
Write | 文字列を書き込む | 書き込み例 |
WriteBlankLines | 改行文字を書き込む | 書き込み例 |
WriteLine | 文字列と改行を書き込む | 1行単位での書き込み例 |
プロパティ
TextStreamオブジェクトは、次のプロパティを持っています。
プロパティ名 | 内容 | 使用例 |
---|---|---|
AtEndOfLine | 現在位置が行末かどうか | 1行単位での読み込み例 |
AtEndOfStream | 現在位置が末尾かどうか | 文字数単位での読み込み例 |
Column | 改行文字からの現在位置(1から) | 文字数単位での読み込み例 |
Line | 現在の行番号(1から) | 1行単位での読み込み例 |
TextStreamオブジェクト使用例
次のテキストファイルの読み込み例、または書き込みでの生成例を紹介します。
改行は、vbCrLfです。
1234567890[CR][LF]
1234567890[CR][LF]
1234567890[CR][LF]
1234567890[CR][LF]
1234567890[CR][LF]
一括読み込み例
ファイルの内容を一括で読み込むときは、ReadAllメソッドを使用します。
Sub readAllSample()
Const fileName As String = "C:\Users\xxxx\Documents\text.txt"
Dim fso As New Scripting.FileSystemObject
Dim stream As TextStream
Set stream = fso.OpenTextFile(fileName)
Dim textData As String
With stream
textData = .ReadAll
.Close
End With
Debug.Print textData
End Sub
実行すると、ファイルの内容がそのままイミディエイトウィンドウに表示されます。
1234567890
1234567890
1234567890
1234567890
1234567890
文字数単位での読み込み例
文字数単位で読み込むときは、Readメソッドを使用します。
読み飛ばすときは、Skipメソッドを使用します。
最後まで読み込んだかどうかの判定は、AtEndOfStreamプロパティで行います。
また、Columnプロパティで先頭、または改行からの位置を確認できます。
次の例は現在位置を表示後、3文字読み込み、3文字読み飛ばしを繰り返しています。
Sub readSample()
Const fileName As String = "C:\Users\xxxx\Documents\text.txt"
Dim fso As New Scripting.FileSystemObject
Dim stream As TextStream
Set stream = fso.OpenTextFile(fileName)
Dim textData As String
Debug.Print "********Start"
With stream
Do Until .AtEndOfStream
Debug.Print "現在位置:" & .Column
textData = .Read(3)
Debug.Print ">" & textData
If Not .AtEndOfStream Then .Skip (3)
Loop
.Close
End With
Debug.Print "********End"
End Sub
ストリームの最後まで読み取った時点でSkipメソッドを実行するとエラーになります。
そこで、AtEndOfStreamプロパティを参照してからSkipメソッドを実行しています。
コードを実行すると、次のような内容がイミディエイトウィンドウに表示されます。
********Start
現在位置:1
>123
現在位置:7
>789
現在位置:2
>234
現在位置:8
>89
現在位置:3
>345
現在位置:9
>9
現在位置:4
>456
現在位置:10
>
1
現在位置:5
>567
現在位置:11
>
********End
改行はvbCrLfなので2文字として扱われます。
空欄の行は改行コードで改行されています。
1行単位での読み込み例
1行単位で読み込むときは、ReadLineメソッドを使用します。
1行単位で読み飛ばすときは、SkipLineメソッドを使用します。
行末のコードはドキュメント等に明確な記述がありません。
動作確認したところ、vbLf(&H0a)とvbCrLf(&H0d0a)を改行コードとして認識していました。
Line Input #は vbCr(&H0d)とvbCrLf(&H0d0a)を改行コードとして認識します。
そのため改行コードがvbLfまたはvbCrのテキストファイルは、Line Input #で読み込めてもReadLineメソッドで読み込めない、またはその逆という現象がおきるので注意が必要です。
最後まで読み込んだかどうかの判定は、AtEndOfLineプロパティで行います。
また、Lineプロパティで現在の行番号を確認できます。
次の例は現在の行番号を表示後、1行読み込み、1行読み飛ばしを繰り返しています。
Sub readSample()
Const fileName As String = "C:\Users\xxxx\Documents\text.txt"
Dim fso As New Scripting.FileSystemObject
Dim stream As TextStream
Set stream = fso.OpenTextFile(fileName)
Dim textData As String
Debug.Print "********Start"
With stream
Do Until .AtEndOfLine
Debug.Print "現在行:" & .Line
textData = .ReadLine
Debug.Print ">" & textData
If Not .AtEndOfLine Then .SkipLine
Loop
.Close
End With
Debug.Print "********End"
End Sub
最終行まで読み取った時点でSkipLineメソッドを実行するとエラーになります。
そこで、AtEndOfLineプロパティを参照してからSkipLineメソッドを実行しています。
コードを実行すると、次のような内容がイミディエイトウィンドウに表示されます。
********Start
現在行:1
>123456789
現在行:3
>123456789
現在行:5
>123456789
********End
書き込み例
ファイルに書き込むときは、まずはTextStreamオブジェクトをForWritingモードで開きます。
Writeメソッドで文字列を書き込みます。
WriteBlankLines(n)メソッドで、n個の改行コードを書き込むことができます。
書き込まれる改行コードはドキュメント上に明確な記述がありません。
Sub writeSample()
Const fileName As String = "C:\Users\xxxx\Documents\text.txt"
Dim fso As New Scripting.FileSystemObject
Dim stream As TextStream
Set stream = fso.OpenTextFile(fileName, ForWriting)
Dim textData As String
textData = "1234567890"
Dim i As Integer
With stream
For i = 0 To 4
.Write textData
.WriteBlankLines 1
Next
.Close
End With
End Sub
作成されたテキストファイルは、次のような内容になっています。
1234567890
1234567890
1234567890
1234567890
1234567890
改行コードは、vbCrLf(&H0a0d)が書き込まれていました。
1行単位での書き込み例
1行単位でファイルに書き込むときは、まずはTextStreamオブジェクトをForWritingモードで開きます。
WriteLineメソッドで文字列を書き込むと直後に改行コードが書き込まれます。
WriteメソッドとWriteBlankLines(1)と同じ結果になります。
書き込まれる改行コードはドキュメント上に明確な記述がありません。
Sub writeSample()
Const fileName As String = "C:\Users\xxxx\Documents\text.txt"
Dim fso As New Scripting.FileSystemObject
Dim stream As TextStream
Set stream = fso.OpenTextFile(fileName, ForWriting)
Dim textData As String
textData = "1234567890"
Dim i As Integer
With stream
For i = 0 To 4
.WriteLine textData
Next
.Close
End With
End Sub
作成されたテキストファイルは、次のような内容になっています。
1234567890
1234567890
1234567890
1234567890
1234567890
改行コードは、vbCrLf(&H0a0d)が書き込まれていました。
更新日:2024/01/18
関連記事
スポンサーリンク
記事の内容について
こんにちはけーちゃんです。
説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。
ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php
このサイトは、リンクフリーです。大歓迎です。