Excel VBA入門 | FileSystemObject-OpenTextFileメソッド(ファイルを開く)

Excel VBA入門

公開日:2017年6月6日

FileSystemObjectオブジェクトは、Windowsスクリプトテクノロジの1つであるScriptランタイムに属したオブジェクトです(Excel VBA上ではScriptingのメンバに位置づけされています)。

ここでは、ファイルを開く方法としてFileSystemObjectオブジェクトのOpenTextFileメソッドを使用する方法を解説します。

1.基本形

FSO.OpenTextFile(FileName[, Iomode[, Create[, Format]]]) →オブジェクト(ファイル)を開く(TextStream型)

変数説明
FSOFileSystemオブジェクト変数。FileSystemオブジェクトとして宣言して格納した変数です。
引数説明
FileNameファイル名。相対パスまたは絶対パスで指定します。
Iomode省略可能。ファイルの書き込みについて指定します。既定はForReading。指定する値は下記の「定数(Iomode)」を参照。
Create省略可能。FileNameで指定したファイルが存在しなかった場合の対応についてTrue/Falseで指定します。新規にファイルを作成する場合はTrueを、作成しない場合にはFalseを指定します。既定はFalseです。
Format省略可能。ファイル形式(文字コード)を指定します。指定する値は下記の「定数(Format)」を参照。既定はASCIIコードです。
定数(Iomode)(値)説明
ForReading(1)読み取り専用で開きます。
ForWriting(2)書き込み専用で開きます。
ForAppending(8)ファイルを開き、追記します。
定数(Format)説明
TristateTrueUnicodeコードとして開きます。
TristateFalseASCIIコードとして開きます。
TristateUseDefaultシステム既定値を使用してファイルを開きます。Windowsのシステム既定値はANSIコードになります。

正常に動作した場合には、TextStream型のオブジェクト(ファイル)を開きます。

2.使用例

次の例では、デスクトップ上の「Test.txt」という名前のテキストファイルを開き、「12345」と書き込みした後に閉じます。

Sub テキストファイルを開く()

Dim FSO As New FileSystemObject  '(1)
Dim MyText As TextStream         '(2)
'変数名は自由に設定してください。

Set MyText = FSO.OpenTextFile("C:\Users\ユーザー名\Desktop\Test.txt", ForWriting) '(3)
'ユーザー名はあなたのPC環境に合わせて書き換えてください。

MyText.Write "12345"             '(4)
MyText.Close                     '(5)

End Sub

【解説】

(1)Dim FSO As New FileSystemObject
→FileSystemObjectオブジェクトを使用する際のおまじないです。FileSystemObjectオブジェクト変数FSOの宣言と変数FSOにFileSystemObjectオブジェクトの参照への代入を同時に1行で行っています。

おまじないには事前バインディングと実行時バインディングがありますが、ここでは事前バインディングを使用しています。

なお、FileSystemObjextオブジェクトを使用する場合には前もって、参照設定で「Microsoft Scripting Runtime」を有効にしておきます。

※FileSystemObjectオブジェクトの設定は「Excel VBA入門 | FileSystemObjectオブジェクト(概要)」を参照ください。

(2)Dim MyText As TextStream
→OpenTextfileで作成するファイルはFile型ではなく、TextStream型のオブジェクトです。

従って、変数MyTextに作成ファイルを代入する場合には、File型ではなく、TextStream型で宣言する必要があります。

もし、File型で宣言した場合には、(3)及び(4)でエラーが発生します(それぞれの解説を参照)。

(3)Set MyText = FSO.OpenTextFile("C:\Users\ユーザー名\Desktop\Test.txt", ForWriting)
→FileSystemオブジェクトのOpenTextfileメソッドを使用して、デスクトップ上のTest.txtを書き込み専用で開いています。

いくつか理解するためのポイントがありますので、ポイント毎に分けて解説します。

【ポイント1:String型との違い】
作成したファイルはオブジェクト型(OpenTextfileメソッドで開くオブジェクトは、オブジェクト型のうち、TextStream型)です。String型と間違えやすいので注意が必要です(セル自体の取得とセルの値の取得の違いと似ています)。

そこで、TextStream型のオブジェクト変数としてMyFileを(2)で宣言しました。一方で、ファイルを開くのではなく、ファイル名を取得するのであれば、TextStream型ではなく、String型を宣言します。

【ポイント2:Setステートメント】
オブジェクト変数(今回はTextStream型)にオブジェクトを代入する場合には、Set ~ステートメントを使用して設定します。ファイル名であればString型の変数に代入するため、「Set~」ステートメントは使用しません(ただし、(2)でString型の変数として変数を宣言する必要があります)。

【ポイント3:TextStreamオブジェクト】
FileSystemオブジェクトのOpenTextfileメソッドで作成したファイルは上述の通り、TextStream型のオブジェクトになりますが、このTextStreamオブジェクトは、FileSystemオブジェクトやFileオブジェクト、Driveオブジェクト、Folderオブジェクトと同列に並ぶ扱いで、FileSystemオブジェクトの系統に属するオブジェクトになります(すなわち、Sprictingのメンバー)。

TextStreamオブジェクトには、テキストファイルを操作する様々なプロパティやメソッドが用意されています。後述(4)や(5)で使用しているWriteメソッドやCloseメソッドはTextStreamオブジェクトのメソッドになります。

一方でMyTextはTextStreamオブジェクトであるため、Fileオブジェクトのプロパティやメソッドを使用することはできません。この点、「ファイル」という文言や、Fileオブジェクトも同じくファイルを操作するオブジェクトであることから、TextStreamオブジェクトとFileオブジェクトを混同しやすいので注意が必要です。

例えば、(4)の代わりに「MsgBox MyText.Name」として、ファイル名を表示するプログラムを実行するとコンパイルエラーが発生します。なぜならばNameプロパティはTextStreamオブジェクトではなく、Fileオブジェクトのプロパティだからです。

Excel VBA CreateTextFile

【ポイント4:エラーが発生する場合】
例えば、(2)で「Dim MyText As File」とTextStream型ではなく、File型で変数MyTextを宣言した場合には、(3)で実行時エラーが発生します(実行時エラー13。ただし今回のサンプルでは、この実行時エラーが発生する前に(4)でコンパイルエラーが発生しますが)。

くどいようですが、OpenTextfileメソッドはTextStreamオブジェクトを作成するため、ファイルであってもFile型で宣言してはいけません。

Excel VBA CreateTextFile

それに対して(2)を「Dim MyText As Object」とMyTextをObject型で宣言した場合には、正常に動作します。なぜならば、Object型はTextStream型やFile型を包含する、より上位に位置するオブジェクトだからです。

(4)MyText.Write "12345"
→TextStreamオブジェクトのWriteメソッドを使用して開いたTest.txtに「12345」の文字列を書き込みます。

もし、(2)で「Dim MyText As File」とTextStream型ではなく、File型で変数MyTextを宣言した場合には、この(4)でコンパイルエラーが発生します。理由は上述(2)や(3)で解説している通り、データ型が異なる(TextStream型ではなく、File型で宣言してしまった)からです。

Excel VBA CreateTextFile

(5)MyText.Close
→TextStreamオブジェクトのCloseメソッドを使用してTest.txtを閉じます。

【補足1】引数Iomodeの設定について

サンプルコードでは引数Iomodeには「ForWriting」を設定しました。なぜならば(4)で「12345」を書き込むからです。

これに対して、例えば今回のサンプルコードで引数Iomodeを省略、またはForReading(「1」でも同じ)に設定した場合には、(4)で実行時エラーが発生します(実行時エラー54)。なぜならば、読み込み専用でファイルを開いたにも関わらず、(4)で「12345」を書き込もうとしたからです。

Excel VBA OpenTextFile

次に「ForWriting」ですが、上書きをします。従って、既にTest.txtに何らかの書き込みがあった場合、サンプルコードを実行すると、「12345」だけが書き込まれた状態になりますので、注意が必要です。

これに対して、引数Iomodeに「ForAppdnding」を設定した場合には、既存の書き込みはそのままで「12345」が追記されます。

【補足2】引数Createの設定について

サンプルコードでは引数Createを省略しています。既定はFalseであるため、もし、デスクトップ上にTest.txtが存在しない場合には(3)で実行時エラーが発生します(実行時エラー53)

Excel VBA OpenTextFile

ファイルが存在しない場合にも正常にコードを動作させるのであれば、引数Createには「True」を設定します。

【補足3】引数Formatの設定について

サンプルコードでは引数Formatを省略しています。既定はASCIIコードです。ASCIIコードでは全角文字に2バイト、半角文字に1バイトが必要です。Windowsシステムの既定はANSIですが、ANSIも必要なバイト数は同じです。

これに対してUnicodeコードは全角文字、半角文字とも2バイトになります。

例えば、サンプルコードの(4)を「MyText.Write "12345あいうえお"」に変更した場合、コードを実行すると、Test.txtのファイルサイズは15バイトですが、もし、(3)で引数FormatにUnicodeを設定してコードを実行すると、ファイルサイズは22バイトになります(Unicodeではテキストファイル作成時点で2バイトを要するので、2バイト×10文字に2バイトを足した22バイトになります)。

【補足4】TextStreamオブジェクトの位置づけ

TextStreamオブジェクトはFileSystemObjectオブジェクトの系統に属すると記載しましたが、TextStreamオブジェクトはFileSystemObjectオブジェクトに属する訳ではありません。

この2つのオブジェクトはVBE上では同じSctiptingライブラリのメンバーになります(同列の扱い)。従って、FileSystemObjectオブジェクトとFileオブジェクトにはそれぞれ別々のプロパティやメソッドが存在します。FileSystemObjectオブジェクトのプロパティやメソッドをファイルオブジェクトでは扱うことはできません。またその逆もしかりです。

この点、ややこしい話になるのは言葉の問題によるものです。「MSDN ライブラリ」を見ると分かりますが、FileSystemObjectオブジェクトやTextStreamオブジェクトをまとめて「FileSystemObjectオブジェクト」という用語で説明しています。

要するに「FileSystemObjectオブジェクト」を2つの意味で用いていることが、VBA上のFileSystemObjectオブジェクト系統の文法の理解を難しくしています。