本稿で紹介する「テキストファイルの操作」は、UTF-8形式のテキストファイルを対象にしています。Shift-JIS形式のファイルを扱うときは、下記ページをご覧ください。
正確には「UTF-8形式のファイル」ってのも、ちょっと変な表現なんですけどね。ファイルの形式じゃなくて、そこで使われている文字コードが"UTF-8"だよってことなんですが。まぁ、細かいことはいいとして。ここでは面倒なので「UTF-8形式のファイル」「Shift-JIS形式のファイル」という呼び方をします。
UTF-8の文字コードが記録されたテキストファイルを、上記「テキストファイルを操作する」で解説した方法で読み込むと、望んだ結果になりません。ちょっと、やってみましょう。
UTF-8の文字コードで書かれたデータを読み込むときは、ADO(ActiveX Data Objects)という仕組みを使います。ADOとは何か?気になる方は、ご自身で調べてください。ADOを使って、UTF-8形式のファイルを読み込むときは、次のようにします。
Sub Sample1() Dim buf As String, Target As String Target = "D:\Work\UTF-8のテキスト.txt" With CreateObject("ADODB.Stream") .Charset = "UTF-8" .Open .LoadFromFile Target buf = .ReadText .Close MsgBox buf End With End Sub
簡単に説明します。
CreateObject("ADODB.Stream")で、ADOを使えるようにします。
Charset = "UTF-8"というのは、UTF-8形式の文字コードでお願いします、という意味です。もちろん、UTF-8以外の文字コードを指定して読み込むことも可能です。どんな文字コードを扱えるかは、
HKEY_CLASSES_ROOT\MIME\Database\Charset
のサブキーで確認できます。↑これの意味が分からない方は、聞かなかったことにしてください。
Openは、テキストデータを操作するStreamオブジェクトを開きます。まぁ、決まり事だと思ってください。
LoadFromFile TargetでテキストファイルのデータをStreamに読み込みます。ここでは、ファイルのフルパスを変数Targetに入れて、その変数を指定していますが、もちろん「.LoadFromFile "D:\Work\UTF-8のテキスト.txt"」のように書くことも可能です。
ReadTextメソッドは、Streamからデータを読み込みます。この書き方の場合は、すべてのデータを読み込みます。上記コードでは、読み込んだデータを、変数bufに入れています。変数に入っちゃえば、こっちのもんです。あとは、どーとでもなります。
Closeで、開いたStreamを閉じます。開いたものは閉じる。人として当然ですね。
上記のように、
buf = .ReadText
とすれば、テキストファイルのすべてのデータを読み込めます。ただし、ここでちょっとした注意が必要です。ここでは、次のようなデータを読み込みました。
このデータを読み込むと、最後にひとつ改行コードが追加されて、次のようになります。
データ全部を一気に読み込むなら、上のようにすればいいです。しかし、CSVファイルのように、1行ずつ読み込みたいこともありますよね。もちろん、データ全部を読み込んだ後で、全データを改行コードで分割すれば、1行ずつの配列を作れます。次のようなCSVデータで、やってみましょうか。
Sub Sample2() Dim buf As String, Target As String, i As Long Dim tmp1 As Variant, tmp2 As Variant, j As Long Target = "D:\Work\UTF-8のテキスト.csv" With CreateObject("ADODB.Stream") .Charset = "UTF-8" .Open .LoadFromFile Target buf = .ReadText .Close tmp1 = Split(buf, vbCrLf) For i = 0 To UBound(tmp1) tmp2 = Split(tmp1(i), ",") j = j + 1 Range(Cells(j, 1), Cells(j, 3)) = tmp2 Next i End With End Sub
まぁ、これでもいいんですけど、最後の方、ちょっと難しいですよね。ただでさえ、配列は苦手な人が多いです。頭の中で2つの配列をイメージするのは、簡単な作業ではありません。実は、今回のADOでも「テキストファイルを操作する」で解説したように、1行ずつ読み込むことができます。次のようにします。
Sub Sample3() Dim buf As String, Target As String, i As Long Dim tmp As Variant, j As Long Target = "D:\Work\UTF-8のテキスト.csv" With CreateObject("ADODB.Stream") .Charset = "UTF-8" .Open .LoadFromFile Target Do Until .EOS buf = .ReadText(-2) i = i + 1 tmp = Split(buf, ",") For j = 0 To UBound(tmp) Cells(i, j + 1) = tmp(j) Next j Loop .Close End With End Sub
データを読み込むReadTextメソッドには引数NumCharsを指定できます。すべてのデータを読み込むには「-1」を指定し、1行ずつ読み込むときは「-2」を指定します。本当はこの「-1」と「-2」には、ADOの方で定数が定義されているのですが、VBAからCreateObjectで呼び出すときは、その定数を使えません。なので実体の「-1」または「-2」を指定します。なお、引数を省略すると「-1」が指定されたものとみなします。
1行を区切るセパレーターは、標準ではWindowsで一般的に使われている改行コード「CRLF」が使われますが、「CR」や「LF」を指定することも可能です。まぁ、そのへんになると、また難しくなりますから、ここでは割愛します。
EOSプロパティは、何行目を読み込むかという、いわゆる"読み取りポイント"が、Streamの最後(End Of Stream)に到達しているかどうかを表します。VBAのEOF関数みたいなものです。