VBAで文字列に改行があるか簡単に調べる方法
 
	InStr関数で文字列内を検索
InStrは、文字列の中から「探したい文字」や「部分文字列」を見つける関数です。見つかった位置(1から数える)を返します。見つからない場合は0になります。戻り値が0より大きければ「含まれている」と判断できます。
VBAでは、改行を表す特別な文字があります。この記事ではCR、LF、CRLFという3種類の改行コードを扱います。InStrでこれらを順番に探すことで、改行が入っているかどうかを簡単に確かめられます。
InStrの主な引数は「開始位置」「検索対象(文字列)」「検索する文字」「比較方法」です。比較方法はvbBinaryCompare(バイナリ比較)とvbTextCompare(テキスト比較)があります。改行コードの検出では、大文字小文字の違いは関係しないため、どちらでも結果は同じになります。
InStr関数による改行コードの検索
最短での判定は、InStrでvbCrLf→vbCr→vbLfの順に探す方法です。vbCrLf(2文字)を先に探すと、CRLFとCR/LFの区別がしやすくなります。
- 例(概念):
- 1行目:pos = InStr(1, s, vbCrLf)
- 2行目:If pos = 0 Then pos = InStr(1, s, vbCr)
- 3行目:If pos = 0 Then pos = InStr(1, s, vbLf)
- 4行目:含まれていれば pos > 0
 
- 1行目:
InStrは先頭からの位置を返すため、最初の改行の場所も同時に分かります。必要に応じて、2回目以降の改行を探したい場合は、見つかった位置の次から再度InStrを呼び出します。
ミニQA:InStrで大文字小文字やバイナリ比較は?
- Q. 比較方法はどちらを使えばよいですか?
- A. 改行コードは制御文字なので、vbBinaryCompareでもvbTextCompareでも結果は同じです。既定値のままでも問題になりにくいです。
- Q. 先頭や末尾の改行も見つかりますか?
- A. 見つかります。InStrは文字列全体を対象にします。
- Q. 改行が複数ある場合は?
- A. 最初の位置が返ります。次を探すときは、その位置+1から再検索します。
3種類の改行コード(CR/LF/CRLF)
改行コードには大きく3種類あります。歴史的な経緯でOSごとに慣習が異なります。VBAでは定数が用意されているため、記号やエスケープ表現を覚えなくても扱えます。
- CR(キャリッジリターン):復帰。タイプライターで行頭に戻る動きに相当
- LF(ラインフィード):改行。次の行に送る動きに相当
- CRLF:- CRと- LFを続けた2文字の改行
以下の表に、代表OSやVBA定数、エスケープ記法をまとめます。
| コード | 名称 | 代表OS/慣習 | VBA定数 | 文字列表現例 | 
|---|---|---|---|---|
| CR | 復帰 | 旧Mac OSなど | VbCr | \r | 
| LF | ラインフィード | Unix/Linux、現行の多くのツール | VbLf | \n | 
| CRLF | CR+LF | Windows系の多くのツール | VbCrLf | \r\n | 
混在データも珍しくありません。ファイルを別ツールで編集した、コピー&貼り付けで持ち込んだ、などの理由で、1つの文字列に複数の改行コードが入ることがあります。
ミニQA:改行コードは混在する?対処は?
- Q. 1つの文字列にCRとLFが混在することはありますか?
- A. あります。異なる環境から持ち込まれたデータで起こります。
- Q. どう扱えばよいですか?
- A. まず種類を把握してから、必要に応じて1種類にそろえます(正規化)。そろえる際は後述の順序に注意します。
改行コードの判定
目的に応じて、次の2段階に分けると整理しやすくなります。
1. 「改行があるか」を判定(有無)
2. 「どの種類か」を判定(種類)
ここではどちらも、コピーしてすぐ使える最小の関数として示します。
改行コードの有無を判定する関数
以下は、文字列sに1つでも改行があればTrueを返す関数の例です。CRLF→CR→LFの順で探します。
- 関数の全体(行ごと):
- Function HasNewline(ByVal s As String) As Boolean
- HasNewline = (InStr(1, s, vbCrLf) > 0) Or _
- (InStr(1, s, vbCr) > 0) Or _
- (InStr(1, s, vbLf) > 0)
- End Function
 
使い方は、If HasNewline(text) Then ...のように呼び出します。戻り値がTrueなら改行を含みます。
改行コードの種類を判定する関数
最初にCRLFを探し、次にCR、最後にLFを探すと、2文字の改行を正しく見分けられます。戻り値は文字列にすると扱いやすいです。
- 関数の全体(行ごと):
- Function NewlineKind(ByVal s As String) As String
- If InStr(1, s, vbCrLf) > 0 Then
- NewlineKind = "CRLF"
- ElseIf InStr(1, s, vbCr) > 0 Then
- NewlineKind = "CR"
- ElseIf InStr(1, s, vbLf) > 0 Then
- NewlineKind = "LF"
- Else
- NewlineKind = "None"
- End If
- End Function
 
種類が分かれば、後続の処理(正規化や分割)に使えます。複数の種類が混在する場合は、先にCRLFを検知してから、残りを追加で検査します。
ミニQA:長文・大量データでのパフォーマンスは?
- Q. 何万文字もの長文でも大丈夫ですか?
- A. InStrは軽量です。数回の呼び出しなら多くのケースで問題になりにくいです。大量のループ処理では、1回の走査で複数条件を判定する方法も検討してください。
- Q. 複数行を分割する最短の方法は?
- A. 種類を問わず分割したい場合は、いったんCRLF→LFの順に統一(正規化)してからSplitを使うと実装が簡単です。
- Q. 文字コードの違いは影響しますか?
- A. 影響することがあります。テキストの読み込み時に文字化けがあると、改行が期待どおりに入らない場合があります。
使用例
ここでは、実務でありがちな3つの場面を例に、関数の使い方を示します。
1. シート入力の検証:セル内に改行が含まれるかチェックして、含まれていれば注意表示
2. CSV取込前の確認:取り込み対象の行に改行が混在していないかを事前に検査
3. ログ整形:外部ログを1種類の改行にそろえてから行単位に分割
- 例1:セル内の改行を検出してフラグを立てる(概念)
- Dim s As String: s = Range("A2").Value
- If HasNewline(s) Then Range("B2").Value = "改行あり"
 
- 例2:CSV文字列の改行を統一してから分割する(概念)
- Dim s As String: s = ReadAllText(path)
- s = Replace(s, vbCrLf, vbLf)
- s = Replace(s, vbCr, vbLf)
- Dim lines() As String: lines = Split(s, vbLf)
 
- 例3:種類に応じて処理を変える(概念)
- Select Case NewlineKind(s)
- Case "CRLF": ' Windows系の扱い
- Case "CR": ' 旧Mac系の扱い
- Case "LF": ' Unix系の扱い
- Case Else: ' 改行なし
- End Select
 
フォーム入力やユーザーファイルの取り込みでは、改行を禁止したい項目もあります。その場合は、最初にHasNewlineで弾くのが簡単です。許可する場合でも、改行が複数の種類で混ざると後工程が複雑になります。早い段階で正規化する方針が管理しやすくなります。
ミニQA:Worksheet関数やフォーム入力と組み合わせできる?
- Q. データ検証の入力規則だけで防げますか?
- A. セル内改行はAlt+Enterで入力できるため、完全には防げません。VBA側のチェックと併用すると確実です。
- Q. ユーザーフォームのTextBoxで改行を禁止できますか?
- A. EnterKeyBehaviorやMultiLineの設定で制御できます。禁止したい場合は単一行にします。
- Q. 既存データの改行を一括で整える方法は?
- A. 読み込み時にReplaceでvbCrLf→vbLfの順に置換し、最後にSplitで分割するのが分かりやすいです。
LFだけのチェックは危険
LFだけを探すコードは、一見シンプルですが、CRLFを見落とす可能性があります。例えば、InStr(s, vbLf) > 0だけを条件にすると、CRLFのケースでもTrueになります。CR単独の改行は見落としになります。安全に判定するには、2文字のCRLFを先に検出し、その後にCRとLFを個別に見る順序が大切です。
また、改行の正規化で順序を誤ると、CRLFが二重に置換されることがあります。次の順番であれば安全です。
1. 先にCRLFをLFへ置換
2. 次にCRをLFへ置換
この順序なら、CRLFの中のCRだけが先に置換される、といった中途半端な状態を避けられます。
ミニQA:混在検知や正規化の安全な順番は?
- Q. 混在を検知するには?
- A. まずCRLFの位置を探し、見つかったらフラグを立てます。次にCR、最後にLFを探します。複数の種類が見つかったら「混在あり」と判断できます。
- Q. 正規化はどの順番が安全?
- A. CRLF→LFの順に置換し、その後CR→LFに置換します。これで二重置換のリスクを避けられます。
- Q. 置換後に空行が増えることはありますか?
- A. あります。空行の扱いは要件に合わせて別途調整してください。
まとめ
InStrを使えば、短いコードで改行の有無を判定できます。さらに、CRLF→CR→LFの順に探せば、種類の判定も安全に行えます。実務では、読み込み直後や入力直後の段階で、関数を使ってチェックするのが管理しやすいです。混在がある場合は、順序を守って正規化してから分割や解析を行うと、後工程の不具合を減らせます。
最小の持ち物としては、HasNewlineとNewlineKindの2つの関数を用意しておくと便利です。どちらもInStrだけで完結し、依存がありません。必要に応じて、正規化用のReplace処理を組み合わせて使ってください。
ミニQA:よくある誤判定と確認手順は?
- Q. LFのみを探してCRLFを見落としていました。どう直す?
- A. 先にCRLFを探し、その後でCRとLFを探す手順に変えます。
- Q. 文字化けで改行が消えたように見えます。
- A. 文字コードの違いが原因の可能性があります。読み込み方法と保存形式を確認します。
- Q. vbCrやvbLfの直書きはできますか?
- A. Chr$(13)やChr$(10)でも表現できますが、読みやすさの面でVBA定数の使用が無難です。
 
	