VBAでCSV解析を実践するための記法とレールロード図
Copyright © 2026 LWP 山中 一弘
本資料は、出典を明記いただければ、商用・非商用を問わず、ご自由に複製・改変・再配布していただけます。なお、著作権表示は改変せず、そのまま記載してご利用くださいますようお願いいたします。
記事要約
CSV解析を実装するには、コードを書く前にCSVの記法を理解する必要があります。
CSVはテキストファイルですが、実際にはバイト列として保存されています。改行、カンマ、ダブルクオート、EOF、セル内改行をどう見るかを整理しないまま実装すると、すぐに壊れます。
この記事では、VBAによるCSV解析実践のために、記法、CR/LF、DQ、論理行、ABNF、レールロード図を整理します。
本記事の対象とゴール
VBAでCSV解析を学びたい人
CSVを Split で処理して失敗したことがある人
テキスト解析の基礎としてCSVを題材にしたい人
先に結論
CSV解析の入口で学ぶべきことは、次の5つです。
CSVファイルはバイトストリームである
CR、LF、CRLFを文字として意識する
ダブルクオートはフィールドを引用する記号である
フィールド内改行を扱うには、物理行と論理行を分ける必要がある
RFC4180のABNFを、VBAで扱いやすいレールロード図や状態遷移へ変換する
<!-- LWP_REWRITE_EXPANSION_記事110 -->
1. 記法は実装の前に必要である
CSV解析のように分岐が多い処理では、いきなりコードを書くと全体像を失います。先に、どの文字で状態が変わるのか、どの状態でどの文字を許すのかを記法として整理します。
レールロード図や状態遷移表は、そのための道具です。実装者だけでなく、後から読む人が仕様を確認できる形になります。
2. レールロード図で入口と出口を見る
レールロード図は、構文の通り道を図として表します。CSVなら、レコード、フィールド、引用符付きフィールド、通常フィールドを分けて見ることができます。
図にすると、許される入力と許されない入力が見えます。たとえば、引用符を閉じた後に文字が続く場合を許すのか、エラーにするのかを明確にできます。
3. VBA実装へ落とす
図や表で整理したら、VBAでは状態、現在文字、出力バッファ、フィールド一覧、レコード一覧へ分けます。1文字ずつ読み、状態に応じて処理します。
ここで大切なのは、パーサーの中に業務処理を混ぜないことです。CSVを解析する処理はCSVだけを扱い、社員番号や金額などの業務判断は解析後に行います。
CSVはバイトストリームである
CSVを説明するとき、画面上では行ごとに折り返して書きます。
しかし、実際のCSVファイルは、文字が順番に並んだバイトストリームです。
abc,def,ghe CRLFaaa,bbb,ccc CRLFこのように見せると分かりやすいですが、実際には CRLF もファイル内に現れる文字列、または文字コード上の制御文字です。
CSV解析では、「目で見た行」と「データとしての改行」を分けて考える必要があります。
EOFと番兵
ファイル終端は、実際に EOF という文字が入っているわけではありません。
ファイルを読み込んだときに、もう読むものがないことを示す印として扱います。
このような印を番兵と呼びます。
CSV解析のコードでは、実際のデータと重ならない値を終端として使うと、ループが書きやすくなります。
今回の素材では、文字列バッファ全体を読み込んだ後の終端として EOT を置く話が出ていました。ただし、ASCII上の EOT は 0x04、ETX は 0x03 なので、コード上の名前は注意が必要です。
引用されるフィールドと引用されないフィールド
CSVのフィールドは、引用されていても、引用されていなくても構いません。
abc"abc"解析結果としては、どちらも abc です。
ただし、フィールド内にカンマ、改行、ダブルクオートが含まれる場合は、ダブルクオートで囲む必要があります。
"a,b""ab""a""b"VBAでは文字列リテラルにもダブルクオートを使うため、CSV上のダブルクオートとVBAコード上のダブルクオートが混ざって見えます。
ここは、CSVの記号としての DQUOTE と、VBA文字列としての " を分けて考える必要があります。
セル内改行と論理行
Excelでは、セル内改行を含むセルがあります。
このセルをCSVとして出力すると、フィールド内に改行が含まれます。
"hoehoe",123このとき、物理的には複数行に見えます。しかしCSVとしては1つのレコードです。
ここで重要になるのが、物理行と論理行の区別です。
物理行: ファイル上で改行文字によって区切られて見える行
論理行: CSVレコードとしての1行
フィールド内改行があると、物理的な複数行が、CSVから見れば1つの論理行になります。
DQの数で継続を判断する
CSVでセル内改行を扱う代表的な方法の一つは、ダブルクオートの数を見ることです。
ダブルクオートの数が奇数なら、まだ引用フィールドが閉じていない可能性があります。次の物理行を読み足して、論理行を完成させます。
1行目: "abc2行目: def",1231行目だけでは、ダブルクオートが閉じていません。2行目まで読むと閉じます。
ただし、2つ並んだダブルクオート "" は、フィールド内の1つのダブルクオートを表します。この扱いも必要です。
RFC4180のABNFを見る
RFC4180では、CSVの構造がABNFで示されています。
file = [header CRLF] record *(CRLF record) [CRLF]header = name *(COMMA name)record = field *(COMMA field)name = fieldfield = (escaped / non-escaped)escaped = DQUOTE *(TEXTDATA / COMMA / CR / LF / 2DQUOTE) DQUOTEnon-escaped = *TEXTDATACOMMA = %x2CCR = %x0DDQUOTE = %x22LF = %x0ACRLF = CR LFTEXTDATA = %x20-21 / %x23-2B / %x2D-7Eこの定義から、次のことが分かります。
ヘッダは任意
最後のCRLFは任意
レコードはフィールドの並び
フィールドは引用あり、引用なしのどちらか
引用フィールドの中では、カンマやCR/LFをデータとして扱える
レールロード図へ落とす
ABNFは正確ですが、実装を考えるには読みづらいことがあります。
そこで、レールロード図や状態遷移図へ落とします。
素材画像では、ABNFを読み解きながら、右側にトップレベルのレールロード図を書いていました。特に、最後の CRLF が任意であることが重要です。
最後のレコードは、次のどちらでもよいということです。
abc CRLF EOFabc EOFこの違いを考慮しないと、最後の1レコードを取りこぼす実装になります。
2つの実装方針
素材では、セル内改行対策として大きく2つの方法が示されていました。
1つ目は、ダブルクオートの数を数え、奇数であれば物理行が継続しているとみなし、ダブルクオートが閉じるまで読み足してから1つの論理行にまとめる方法です。
2つ目は、物理行を先にまとめず、読み進めながらダブルクオートの数や状態で継続を判断する方法です。
前者は理解しやすく、後者は解析器として自然です。
どちらを選ぶにしても、「見た目の行」と「CSVとしてのレコード」を分けて考えることが重要です。
まとめ
CSV解析は、カンマで分割する処理ではありません。
CSVを正しく扱うには、CR、LF、CRLF、ダブルクオート、フィールド内改行、最後のCRLF省略、EOFを理解する必要があります。
RFC4180のABNFは正確な出発点です。ただし、VBAで実装するには、ABNFをそのまま読むだけでなく、レールロード図や状態遷移へ変換すると分かりやすくなります。
CSV解析は、CSVだけの話ではありません。
テキストを読み、記号を認識し、状態を持ちながら解釈するという、すべてのテキスト解析の基礎になります。
出典メモ- 元Posfie URL: https://posfie.com/@hoehoe1234/p/0fVQeIy
元Posfieタイトル: 2022-03-27 個別指導 VBAによるCSVの解析実践編
投稿者: hoehoe1234
投稿数: 24
画像確認: 画像9点を取得し、記事化時に内容を確認
取得・確認日: 2026-06-11
画像・他者投稿として確認した主な投稿:
@hoehoe1234 2022-03-28 13:41:34: https://x.com/hoehoe1234/status/1508303259731382272
@hoehoe1234 2022-03-28 13:57:02: https://x.com/hoehoe1234/status/1508307153115058178
@hoehoe1234 2022-03-28 14:08:25: https://x.com/hoehoe1234/status/1508310015752679427
@hoehoe1234 2022-03-28 14:20:45: https://x.com/hoehoe1234/status/1508313118786859011
@hoehoe1234 2022-03-28 14:27:06: https://x.com/hoehoe1234/status/1508314716892205062
@hoehoe1234 2022-03-28 14:34:33: https://x.com/hoehoe1234/status/1508316593126002691
@hoehoe1234 2022-03-28 14:47:46: https://x.com/hoehoe1234/status/1508319917464244229
@hoehoe1234 2022-03-28 14:50:12: https://x.com/hoehoe1234/status/1508320530679869442
@hoehoe1234 2022-03-28 14:55:29: https://x.com/hoehoe1234/status/1508321862128128001
参考: RFC 4180 Common Format and MIME Type for CSV Files, https://www.rfc-editor.org/rfc/rfc4180
