VBAでテキストファイルの操作を行うには

VBAでテキストファイルの読み書きを行う場合、特殊な方法を除くと2つの方法があります。

  1. Open、Close、Input、Line Input、Get、Write、Print、Putステートメントを使う。
  2. FileSystemObjectクラスを利用する。

用途によってどちらを使うかを決めることになります。

Open等ステートメントはコードが単純ですが、FileSystemObjectクラスにあるような便利な機能はありません。バイナリファイルを扱う場合はこちらを使います。

FileSystemObjectクラスはメソッドやプロパティの使い方に癖がありますが、ファイルの存在をチェックできるメソッドなどの便利なメソッドが用意されています。

ここではOpen等のステートメントを使ったテキストファイルの操作について説明します。


OpenからCloseまでの流れ

テキストファイルを開いてから読み書きを行いファイルを閉じるまでには以下のいずれかの流れになります。

1. 読み込み(通常ファイル)

1.Open → 2.Line Input → 3.Close

2. 読み込み(CSVファイル)

1.Open → 2.Input → 3.Close

3. 書き込み(通常ファイル)

1.Open → 2.Print → 3.Close

4. 書き込み(CSVファイル)

1.Open → 2.Write → 3.Close


Openステートメント

Open Pathname For Mode [Access access] [lock] As [#] Filenumber [Len = reclength]

Openステートメントを使うと既存のテキストファイルを開いたり、新規テキストファイルを作成したりすることが出来ます。

複数の引数がありますが、ほとんどの場合は必須引数の3つ(PathnameとModeとFilenumber)だけを指定すればOKです。

Pathname 開くテキストファイルのパスをダブルクォーテーションで囲んで指定します。

ドライブ名からファイル名までのフルパスを指定するか、ファイル名だけのどちらかを指定します。

ファイル名だけの場合はカレントフォルダにあるファイルが開かれます。

カレントフォルダはCurDir関数で「CurDir(“C:”)」のようにドライブ名を指定すると調べられます

Mode ファイルをどのように開くのかをキーワードで指定します。

Input シーケンシャル入力モード テキストファイルの内容を先頭から順に参照
Output シーケンシャル出力モード 元のデータをクリアして先頭から書き込み
Append 追加モード 元のデータの後ろに追加書き込み
Binary バイナリモード 16進数のデータの読み書き
Random ランダムアクセスモード テキストファイルの任意の位置から読み書き

シーケンシャル入力、出力モードとはテキストファイルを先頭から終端に向かって読み書きすることを言います。

OutputモードとAppendモードの場合にパスのテキストファイルが存在しない場合はその名前のテキストファイルを新規作成します。

Access ファイルの読み書きを指定します。引数Modeとの組み合わせが不正な場合は構文エラーになります。

たとえば書き込みモードのAppendを指定して読み込みのReadアクセスを指定するなどです。

Read 読み込みのみ
Write 書き込みのみ
Read Write 読み書き両方
lock 開いたファイルを他のアプリケーションなどからアクセスできるようにするかどうかの制限を行います。

Shared 他プロセスからの読み書きを認める
Lock Read 他プロセスからの読み込みを禁止する
Lock Write 他プロセスからの書き込みを禁止する
Lock Read Write 他プロセスからの読み書きを禁止する
Filenumber テキストファイルを一意に認識するための番号を#1から#511の値で指定します。

1ファイルしか扱わないのであれば「#1」としても構いません。

reclength Randamモードを指定した場合は読み書きを行うデータ長を指定します。

それ以外の場合は読み書きを行う変数サイズをInteger型の範囲内(32767以下)で指定します。

Filenumberの指定

引数Modeが書き込みを行う「Output」または「Append」の場合、同じテキストファイルを異なるファイル番号で開こうとしても、先に開いた方に書き込み権限があるためエラーとなり開けません。

引数Modeが「Input」「Binary」「Random」の場合、同じテキストファイルを異なるファイル番号で開くことが可能です。

ただ、いずれにしてもよほどのことが無い限り、同じテキストファイルに対して複数のアクセスを同時に行うようなことは避けた方が無難です。


FreeFile関数

FreeFile関数はテキストファイルを開く際のOpenステートメントで使うことが出来るファイル番号を返します。

ファイル番号が重複しないのであればFreeFile関数を使わずに#1などと書いても構いません。


Closeステートメント

Close #Finenumber

CloseステートメントはOpenステートメントで開かれたファイルを閉じます。

Closeステートメントで閉じられた際のファイル番号は次のテキストファイルのOpenステートメントで使うことが出来るようになります。

Filenumber Openステートメントで指定したファイル番号を指定します。

複数のファイル番号を指定することで一度に複数のファイルを閉じることが可能です。

また、ファイル番号を省略した場合はそれまでにOpenステートメントで開いていたファイルを全て閉じます。

開いていないファイル番号をCloseで指定した場合

Openステートメントとは異なるファイル番号をCloseで指定した場合、エラーは発生せず何も閉じられることなくCloseステートメントは終了します。

手書きで「#1」などとファイル番号を書いている場合にはファイルが閉じられないバグになります。


EOF関数

EOF関数はOpenステートメントでInputモードかRandomモードで開いたテキストファイルの読み込み位置がファイルの終端(End Of File)に達しているかを判定する関数です。

ファイル終端に達している場合はTrueを返し、そうでない場合はFalseを返します。

引数にOpenステートメント時に指定したファイル番号を設定します。

通常はDo Untilループ条件として利用します。


Line Inputステートメント(1行読み込み用)

Line Input #Filenumber , varname

Filenumber Openステートメントで指定したファイル番号を指定します。
varname 読み込んだテキストファイルの行データを格納する変数を指定します。

変数の型はVariant型かString型のいずれかです。

Line InputステートメントはOpenステートメントでInputモードで開いたテキストファイルを改行コード(CRLF、LF、CRのいずれか)までの行単位で読み込みます。

次に読み込むときは次の行の先頭からになります。

改行コード自体は読み込んだデータには含まれません。

EOF(End Of File)まで読み込み可能ですが、それ以上読み込みを行うとエラーになります。

そのためEOF関数を使ってファイル終端かどうかをチェックする必要があります。


Inputステートメント(CSV読み込み用)

Input #Filenumber, Varlist, ・・・

Filenumber Openステートメントで指定したファイル番号を指定します。
Varlist 読み込む文字列を指定します。

Inputステートメントはテキストファイルからカンマ(,)や改行(CRLF、LF、CRのいずれか)があるまでのデータを読み込みます。

読み込んだあとに再度Inputステートメントを使うと次のカンマや改行までが読み込まれます。

引数Varlistを複数指定している場合はカンマが見つかるまでの文字列を各変数に設定します。

InputステートメントはCSVファイルの1項目ずつを読み込む際には適していますが、1行ごとに取得したい場合はLine Inputステートメントの方が適しています。

読み込まれた元のデータがダブルクォーテーションで囲まれていても、Inputステートメントで取得したデータはダブルクォーテーションの囲みは無い状態になります。

読み込む対象のテキストファイルは以下のようなCSVファイルと形式になります。
“aaa”,”bbb”,”ccc”
“1111”,”2222″,”3333″
“aaa”,”bbb”,”ccc”

Line Inputステートメントと同様で、EOF(End Of File)まで読み込み可能ですが、それ以上読み込みを行うとエラーになります。

そのためEOF関数を使ってファイル終端かどうかをチェックする必要があります。


Printステートメント(1行書き込み用)

Print #Filenumber , [ outputlist ]

Filenumber Openステートメントで指定したファイル番号を指定します。
Outputlist 書き込むデータを指定します。

引数outputlistは以下の構文で構成されます。

[ { Spc(n) | Tab [ (n) ] } ] [ expression ] [ charpos ]

Outputlistを構成するSpcとTabとcharposですが、挙動が分かりにくく使い勝手が悪いため使わない方が無難です。

例えばTabですが、タブ文字を書き込むように思いますが実際は空白スペースを書き込みます。

また、引数nもSpnとTabでは設定する値に際があり、Spnは引数nの数だけスペースを書き込みますが、Tabは引数nから1引いた数のスペースを書き込みます。

こういうのは個人的には触りたくないので使わないようにしています。

書き込みたい文字列を事前に編集して、expressionとしてそれを渡す方が柔軟なコードになります。


Writeステートメント(CSV書き込み用)

Write #Filenumber, Outputlist, ・・・

Filenumber Openステートメントで指定したファイル番号を指定します。
Outputlist 書き込むデータを指定します。

複数書き込む場合はカンマで区切って指定します。

WriteステートメントはOpenステートメントでOutputモードやAppendモードで開かれたテキストファイルにCSVファイル形式のデータを書き込みます。

書き込まれたデータはダブルクォーテーションで囲まれます。データ間はカンマで区切られます。

1行単位の書き込みはPrintステートメントの方が適しています。


サンプルコード

行単位で追加書き込みのサンプル



行単位で読み込むサンプル



CSVファイル形式で書き込むサンプル



CSVファイル形式で読み込むサンプル