概要:なぜCSVの行数取得が重要なのか
Excel VBAを用いてCSVファイルを扱う際、最初に行うべき作業は「そのファイルにどれだけのデータが格納されているか」を把握することです。しかし、CSVの行数取得を甘く見ているエンジニアは少なくありません。単にファイルをExcelに読み込んで行数をカウントするのは、小規模なデータであれば問題ありませんが、数万行、あるいは数十万行を超えるCSVを扱う際、このアプローチは致命的なパフォーマンス低下を招きます。
本稿では、Excelのワークシート機能に頼らず、VBAの「FileSystemObject」や「Openステートメント」を駆使して、CSVファイルの行数を高速かつ効率的に取得する方法を徹底解説します。実務において「フリーズしない」「メモリを無駄遣いしない」堅牢なコードを書くための必修スキルをマスターしましょう。
詳細解説:行数取得のための3つの戦略
CSVの行数を取得する方法は、大きく分けて3つのアプローチが存在します。それぞれのメリット・デメリットを理解し、状況に応じて使い分けるのがベテランへの第一歩です。
1. Excelのワークシートに読み込む方法(非推奨):
Workbooks.OpenTextなどでCSVを直接開く方法です。最も手軽ですが、Excelの制限(104万行)を受け、なおかつメモリを大量に消費するため、大規模データには向きません。
2. FileSystemObject (FSO) を使用する方法:
テキストファイルをストリームとして読み込みます。汎用性が高く、コードが直感的で読みやすいのが特徴です。テキストファイルの読み込み処理の標準と呼べる手法です。
3. Openステートメント(Line Input)を使用する方法:
VBAのレガシーな機能ですが、実は最も高速な処理の一つです。FSOよりもメモリ消費が少なく、非常に大きなファイルを扱う際に真価を発揮します。
今回は、実務で最も汎用性が高く、かつ高速な「Line Input」を活用した手法を中心に解説します。
サンプルコード:高速行数取得エンジン
以下に、数百万行のCSVであっても瞬時に行数を取得するサンプルコードを提示します。
Option Explicit
' 指定したCSVファイルの行数を取得する関数
Public Function GetCSVRowCount(ByVal filePath As String) As Long
Dim fileNo As Integer
Dim lineCount As Long
Dim buffer As String
' ファイルが存在するか確認
If Dir(filePath) = "" Then
Err.Raise vbObjectError + 1, , "ファイルが見つかりません。"
End If
' 空いているファイル番号を取得
fileNo = FreeFile
' ファイルをバイナリ読み込みモードで開く
Open filePath For Input As #fileNo
lineCount = 0
' ファイルの終端まで1行ずつ読み込む
Do While Not EOF(fileNo)
Line Input #fileNo, buffer
lineCount = lineCount + 1
Loop
' ファイルを閉じる
Close #fileNo
GetCSVRowCount = lineCount
End Function
' 実行用プロシージャ
Public Sub ShowCSVLineCount()
Dim path As String
path = "C:\Data\LargeSample.csv"
On Error GoTo ErrHandler
MsgBox "行数は " & GetCSVRowCount(path) & " 行です。", vbInformation
Exit Sub
ErrHandler:
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
End Sub
このコードのポイントは、変数の型として「Long」を使用している点です。古いVBAの教材では「Integer」が使われることがありますが、Integerは32,767までしか扱えず、現代のビッグデータ環境では即座にオーバーフローします。常にLong型を使用する習慣をつけましょう。
実務アドバイス:更なる高速化と注意点
プロの現場では、単にコードを動かすだけでなく、以下の観点を取り入れることで、より堅牢なツールに仕上げます。
● 文字コードの罠
VBAのOpenステートメントは、基本的に「Shift-JIS」を前提としています。もしUTF-8(BOMなし)のCSVを読み込む場合、上記コードでは文字化けや行数の誤検知が発生する可能性があります。その場合は、ADO (ADODB.Stream) オブジェクトを使用して文字コードを指定して読み込む必要があります。
● 空行の取り扱い
CSVファイルの中には、意図せず末尾に空行が含まれている場合があります。データとしてカウントすべきか否かをあらかじめ要件定義で明確にし、必要であれば `If Len(Trim(buffer)) > 0 Then lineCount = lineCount + 1` のように条件を組み込みましょう。
● 大容量ファイルへの対応
もしCSVの行数が数百万行を超え、かつ読み込み速度がどうしてもボトルネックになる場合、VBAだけで解決しようとせず、コマンドプロンプトの「find /c /v “”」コマンドを呼び出すという手もあります。VBAから `WScript.Shell` を使ってコマンドを実行し、その結果を取得する方法です。これはVBAがファイルの中身を読み込まないため、圧倒的な速さを誇ります。
まとめ:プロフェッショナルなVBA開発を目指して
CSVファイルの行数取得は、自動化ツール作成における「最初の関門」です。多くの初心者は「とりあえずExcelに開かせてからカウントする」という安易な道を選びますが、それは将来的なトラブルの種を蒔いていることに他なりません。
今回ご紹介した手法は、リソースを極限まで抑えつつ、安定した動作を約束するものです。VBAをただの「事務作業の自動化ツール」としてではなく、「データ処理エンジン」として使いこなすためには、こうした低レイヤーのファイル操作技術が不可欠です。
まずは自身のPCにある適当なCSVファイルでコードを試し、その速度差を体感してください。そして、コードを再利用可能な関数(Function)として個人ライブラリにストックしておくことを強く推奨します。
Excel VBAは、使い方次第で無限の可能性を秘めています。今回学んだ「効率的な行数取得」という武器を手に、より高度なデータ分析自動化の世界へと足を踏み入れてください。あなたの開発するツールが、業務効率を劇的に改善する鍵となることを確信しています。
