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ステートメントで指定したバッファ容量を読み出します。ファイルの末尾だからといって読み出す容量が減ることはありません。ファイル容量を超えて読み出したデータは切り捨てなければなりません