« フレーム構成を表示するコンテキストメニュー拡張 | トップページ | XP + IE7 で、Microsoft Internet Controls の参照設定が変です。 »

2008年6月24日 (火)

テキストファイルの行数を調べる。

よくあるのは、FSOで追加書き込みでオープンして、Lineプロパティを見るものです。

Function NumberOfLines(File)
Const forAppending=8
Dim TStream
Set TStream=CreateObject("Scripting.FileSystemObject").OpenTextFile(File,forAppending)
NumberOfLines=TStream.Line
End Function

しかし、このやり方には以下の問題があります。
出力オープンがエラーになることがある。
行数に1行の誤差が出ることがある。

なら、FSOでReadオープンしてSkipLineで数えれば、そういう問題はありません。

Function NumberOfLines(File)
Dim TStream
NumberOfLines=0
Set TStream=CreateObject("Scripting.FileSystemObject").OpenTextFile(File)
Do While Not TStream.AtEndOfStream
  TStream.SkipLine
  NumberOfLines=NumberOfLines+1
Loop
End Function

でも、性能が気になります。

じゃ、一度にすべて読めば、速い?

Function NumberOfLines(File)
Dim TStream
Set TStream=CreateObject("Scripting.FileSystemObject").OpenTextFile(File)
If Not TStream.AtEndOfStream Then TStream.ReadAll
NumberOfLines=TStream.Line+(TStream.Column=1)
End Function

今度は、メモリが気になります。

そこで、すべて読み飛ばします。

Function NumberOfLines(File)
Dim TStream
Set TStream=CreateObject("Scripting.FileSystemObject").OpenTextFile(File)
Do While Not TStream.AtEndOfStream
  TStream.Skip 1073741824
Loop
NumberOfLines=TStream.Line+(TStream.Column=1)
End Function

ところで、この TStream.Line+(TStream.Column=1) の意味は?

TStream.Line は、UBound(Split(vbLf & TStream..ReadAll,vbLf)) みたいなもので、末尾の改行の有無によって、1行多く数えます。
TStream.Column は、a=Split(vbLf & TStream..ReadAll,vbLf): Len(a(UBound(a)))+1 みたいなものです。
なので、改行の後に文字がない場合(TStream.Column=1)、1を減じます(True=-1)。

« フレーム構成を表示するコンテキストメニュー拡張 | トップページ | XP + IE7 で、Microsoft Internet Controls の参照設定が変です。 »