CSVファイルの行数を取得する|Excel VBA

ファイル操作関連のテクニック

CSVファイルの行数を取得する

(Excel 2000/2002/2003/2007/2010)

CSVファイルをワークシートに展開するときは、CSVファイルをテキストファイルとして扱うと便利です。

ここでは、
「モーグ,www.moug.net,オフパー,水曜配信」
のようなデータが1000行ある"C:\Data\Sample.csv"から、各データをアクティブシートに展開してみましょう。

Sub Sample1()
    Dim buf As String, cnt As Long
    Const TARGET As String = "C:\Data\Sample.csv"
    
    Open TARGET For Input As #1
        Do Until EOF(1)
            Line Input #1, buf
            cnt = cnt + 1
            Cells(cnt, 1).Resize(1, 4).Value = Split(buf, ",")
        Loop
    Close #1
End Sub

あらかじめ各行の要素数が4つと特定していましたので、Resize(1, 4)と決めうちしましたが、読み込んでみるまで要素の数がわからないときは、Split関数の戻り値をUBound関数で調べます。

さて、このようにCSVファイルを読み込むのは簡単なのですが、ひとつ問題があります。
Excel 2003までは、ワークシートの行数が65536しかありません。
これを超えるCSVファイルを読み込むことはできません。
Excel 2007以降でワークシートの大きさが拡大されたとはいえ、限界があることに違いはありません。
CSVファイルをテキストファイルとして操作するときは、事前にそのCSVファイルが何行あるかを調べた方が安心です。

CSVファイルの行数を調べるには、いくつかの方法があります。
行数の少ない(と、あらかじめ分かっている)CSVファイルでなら、一度すべてを読み込んでしまう手もあります。最近のパソコンはとても高速なので、数100行程度のファイルならほとんど一瞬で終了するでしょう。

Sub Sample2()
    Dim buf As String, cnt As Long
    Const TARGET As String = "C:\Data\Sample.csv"
    
    Open TARGET For Input As #1
        Do Until EOF(1)
            Line Input #1, buf
            cnt = cnt + 1
        Loop
    Close #1
    MsgBox Dir(TARGET) & "は、" & cnt & "行あります。"
End Sub

次に、FileSystemObjectを使って行数を調べてみましょう。
TextStreamオブジェクトのLineプロパティは、ファイルに読み書きする行位置を返します。
ファイルを追記モードで開くと書き込み位置が最終行に移動するので、
開いた直後の「 Lineプロパティ - 1」 がファイルの行数になります。
ただし、最終行の行末が改行されていない場合は、Lineプロパティの値がファイルの行数となります。

Sub Sample3()
  Dim FSO As Object
  Const Target As String = "C:\Data\Sample.csv"
  Set FSO = CreateObject("Scripting.FileSystemObject")
  With FSO.OpenTextFile(Target, 8)
    MsgBox Dir(Target) & "は、" & .Line - 1 & "行あります。"
    .Close
  End With
  Set FSO = Nothing
End Sub

すべてのデータを改行コードで区切ったときの要素数を調べる手もあります。

Sub Sample4()
    Dim b_buf() As Byte, s_buf As String
    Const TARGET As String = "C:\Data\Sample.csv"
    
    Open TARGET For Binary As #1
        ReDim b_buf(1 To LOF(1))
        Get #1, , b_buf
        s_buf = StrConv(b_buf, vbUnicode)
    Close #1
    MsgBox Dir(TARGET) & "は、" & UBound(Split(s_buf, vbCrLf)) & "行あります。"
End Sub

データを改行コードで分割するには、Split関数を使います。
Split関数の戻り値は0から始まる配列形式なので、配列の最も大きいインデックス番号がファイルの行数になります。
ファイルのインデックス番号の上限値はUBound関数で取得します。
ファイルの最終行が改行されていない場合は、UBound関数の戻り値に +1 してください。

● 補足 ●

一般に、Windowsで作成したCSVファイルはCR+LFコードで改行されていますが、Unix/Linuxで作成されたファイルはLFコードのみ、Macintoshで作成されたファイルはCRコードのみで改行されていることが多いでしょう。
Sample2で使用しているLine InputステートメントはCR+LFコード、またはCRコードのみで区切られたファイルは1行ずつ読むことができますが、LFコードのみで区切られたファイルは1行ずつ読むことができないため、1行とカウントされてしまいます。
またSample3も、CRコードのみで区切られたファイルは1行とカウントされてしまいます。
Sample4では、Split関数の区切り文字に読み込むファイルで使用されている改行コードを指定することで、どのコードで改行されていてもカウントすることができます。