2005-09-09 Excel VBAで改行コードがLFのファイルを読む
Excel VBAで,CRLF以外の改行コードが含まれたテキストファイルを読み込むコードを作りました。
あらまし
VBAではLine Input # ステートメントを使うと,シーケンシャルファイルから1行ずつ読み込むことができます。
ところで,改行コードがLFのファイルを読み込ませてみたら,Excelが応答しなくなってしまいました。 Line Input # ステートメントは,改行コードがLFのファイルには対応していないようです。
そこでCRLF,LF,CRの三種類の改行コードに対応したコードを作ってみました。
動作概要
- ファイルをバイナリモードで読み出した後,改行コードを認識し1行の文字列に変換する
- バッファを設けて読み出しの効率化を図る
仕様
- 認識する改行コード列はCRLF,LF,CRの三種類
- ファイルの末尾に改行コードがなかった場合にも対応
- MacのVBAに対応
注意事項
- このコードは無保証です
- 細かな挙動は不明です。巨大なファイル,1行がやたらと長いファイル,そもそも改行が一つもないファイルなどを読み込んだ場合にどんな挙動をするか明らかではありません
- VBA歴の浅い人が書いたので,VBAっぽくないコードかもしれません
コード
Const FILEBUFSIZE = 32767 Dim CR As String CR = Chr(13) #If Not Mac Then CR = StrConv(CR, vbFromUnicode) #End If Dim LF As String LF = Chr(10) #If Not Mac Then LF = StrConv(LF, vbFromUnicode) #End If Dim FileNum As Variant FileNum = FreeFile() Open "filename" For Binary Access Read As FileNum Len = FILEBUFSIZE Dim byteBuf(FILEBUFSIZE - 1) As Byte Dim strBuf As String strBuf = "" Dim FileSize As Long FileSize = LOF(FileNum) Do Until EOF(FileNum) Get FileNum, , byteBuf Dim SeekPoint As Long SeekPoint = Seek(FileNum) - 3 If SeekPoint <= FileSize Then strBuf = strBuf & CStr(byteBuf) Else strBuf = strBuf & LeftB(CStr(byteBuf), FILEBUFSIZE - (SeekPoint - FileSize)) End If Dim p1 As Long p1 = 0 Dim p2 As Long p2 = 0 Do p1 = InStrB(1, strBuf, CR, vbBinaryCompare) p2 = p1 If p1 <> 0 Then If LenB(strBuf) < p1 + 1 Then p1 = 0 ElseIf MidB(strBuf, p1 + 1, 1) = LF Then p2 = p2 + 1 End If Else p1 = InStrB(1, strBuf, LF, vbBinaryCompare) p2 = p1 End If If p1 = 0 And EOF(FileNum) And LenB(strBuf) > 0 Then p1 = LenB(strBuf) p2 = p1 End If ' If p1 <> 0 Then Dim head As String Dim tail As String head = MidB(strBuf, 1, p1 - 1) tail = MidB(strBuf, p2 + 1) #If Not Mac Then head = StrConv(head, vbUnicode) #End If Dim CurrentLine As String CurrentLine = head Debug.Print CurrentLine strBuf = tail End If Loop While p1 <> 0 Loop Close FileNum
ほかの方法
(1) FileSystemObjectオブジェクトのReadLineメソッドも,改行コードLFに対応しているそうです(伝聞なので検証なし)。現在は,このFileSystemObjectオブジェクトを使う方法が主流なのかもしれません。
(2) Excelの機能である「外部データの取り込み」を使うと,シートに任意のテキストファイルを読み出すことができます。この機能では改行コードLFのファイルも読めます。VBAヘルプでQueryTablesオブジェクトを調べてみてください。
メモ
- 改行コードの種類。WindowsのVBAの改行コードはCRLF(0x0d-0x0a),MacのVBAの改行コードはCR(0x0d)です
- 文字コード。VBAが出力するテキストファイルの文字コードは,CP932の「はず」です。CP932はSHIFT-JISに拡張文字(たとえば丸で囲んだ数字)を追加した文字コードです
- Unicode。WindowsのVBAでは内部の文字コードをUnicodeで扱っています。テキストファイルをバイナリファイルとして読み出した場合,その文字列はUnicodeとして扱われません。文字列の比較ならびに出力する際は,明示的に文字コードを変換しなければなりません。MacのVBAはUnicodeを採用していないので,文字コードの変換は不要です
- GETステートメント。GETステートメントは,常にOpenステートメントで指定したバッファ容量を読み出します。ファイルの末尾だからといって読み出す容量が減ることはありません。ファイル容量を超えて読み出したデータは切り捨てなければなりません