VBA If文 条件分岐

VBA If文 条件分岐 アイキャッチ画像 マクロ・VBA

1,000件を超える経費精算データを、一つずつ目視で確認して「交通費ならこの勘定科目」「会議費ならこちら」と手入力する作業。私が経理部門に配属されたばかりの頃、最初に出会ったのはそんな非効率な業務だった。数時間かけて終わらせたあとに、入力ミスが見つかってやり直しになる。そんな虚しさを解決してくれたのが、VBAによる自動化だった。

特に条件によって処理を分ける「If文」は、自動化の心臓部と言える。これを使えるようになるだけで、これまで手作業で行っていた判断業務の多くをPCに任せることが可能になる。

ポイント: VBAのIf文は「もし〜なら、◯◯する。そうでなければ△△する」という、実務における判断基準をそのままコードに落とし込むための道具だ。

  1. VBA If文 条件分岐で請求処理を自動化する仕組み
    1. 条件式で使われる比較演算子の役割
    2. If文の「End If」を忘れないための記述法
  2. セルの値によって処理を振り分ける最小単位の構文
    1. Elseを使った二者択一の判断
    2. If文を一行で書く「省略記法」の是非
    3. 条件を満たさない場合の「何もしない」設定
  3. 製造業の在庫管理で役立つ「複数条件」のさばき方
    1. ElseIfを繋げて多段分岐を作る際の注意点
    2. 論理演算子「And」と「Or」の使い分け
    3. 複数のOr条件を効率的に記述する方法
  4. 経理部の月次締めで「If...Then...Else」を使いこなすコツ
    1. ネスト(入れ子)を深くしすぎない工夫
    2. 空白セルの判定「IsEmpty」と「""」の違い
    3. エラーを回避する「Ifステートメント」の定石
  5. 初心者が陥る「End If忘れ」と「インデント」の重要性
    1. Tabキーを使った正しい字下げの習慣
    2. VBE(エディタ)の自動構文チェック機能を活用する
    3. コメントアウトで条件分岐の意図を残す
  6. ElseIfとSelect Caseはどちらがメンテナンスしやすいか
    1. Select Case文への書き換えタイミング
    2. 複数の値をまとめて判定する「Case 1 To 10」
    3. パフォーマンス(実行速度)の比較
  7. 営業部の売上ランク付けでよく使う比較演算子の全知識
    1. 「以上」「以下」の境界値を間違えないコツ
    2. 文字列の「一部」を条件にするLike演算子
    3. 比較演算子を組み合わせた「範囲指定」の定石
  8. Microsoft公式ドキュメントから読み解くIf文の制限事項
    1. Null値の扱いに注意する
    2. ブール型(Boolean)変数を直接評価する
    3. バリアント型(Variant)による意図しない型変換の罠
  9. バージョンを問わず動くコードを書くための注意点
    1. Office 365の新機能との組み合わせ
    2. Mac版Excelでの挙動の差
    3. アドインやライブラリ参照の有無を判定する
  10. 実行速度を落とさないための条件判定の順序
    1. 出現頻度の高い条件を一番上に持ってくる
    2. 重い処理(関数)の呼び出しを後回しにする
    3. 不要なセルアクセスを最小限にする
  11. 複雑な分岐に関するFAQ
  12. 実務の効率を一段階引き上げる書き換えの習慣
    1. 関連記事

VBA If文 条件分岐で請求処理を自動化する仕組み

実務でVBAを使う目的の多くは、大量のデータに対する「判定」と「処理」の繰り返しだ。例えば、営業部の売上リストをチェックし、予算達成率が100%を超えている行だけを赤字にする、といった操作。この「100%を超えているかどうか」を判断するのが条件分岐の役割である。

筆者の経験では、この基本をマスターするだけで、事務職のルーチンワークの8割は自動化の目処が立つ。

VBA If文 条件分岐 - A列に「請求金額」、B列に「入金状態」が入力された売上管理表
A列に「請求金額」、B列に「入金状態」が入力された売上管理表

まずは最もシンプルな形から見ていこう。以下のコードは、セルA2の値が50,000以上の場合に、B2セルに「要確認」と入力するものだ。

Sub SimpleCheck()
    If Range("A2").Value >= 50000 Then
        Range("B2").Value = "要確認"
    End If
End Sub

この構文は、If 条件式 Then で始まり、最後に End If で閉じるのがルールだ。

条件式で使われる比較演算子の役割

If文を使いこなすには、比較演算子を正しく理解しておく必要がある。実務で頻出するのは以下のものだ。

演算子 意味
= 等しい If Range(“A1”).Value = “完遂” Then
<> 等しくない If Range(“A1”).Value <> “” Then(空白でない場合)
> より大きい If Range(“A1”).Value > 100 Then
< より小さい If Range(“A1”).Value < 0 Then
>= 以上 If Range(“A1”).Value >= 1000 Then
<= 以下 If Range(“A1”).Value <= 500 Then

ここで初心者がつまずきやすいポイントを一つ。文字列を比較する際は、必ず " "(ダブルクォーテーション)で囲む必要がある。例えば「営業部」という文字を探したいなら "営業部" と書かなければならない。これを忘れてエラーになり、30分以上悩んでしまう受講生を研修でよく見かける。

If文の「End If」を忘れないための記述法

コードを書いている途中で End If を書き忘れ、実行時に「コンパイルエラー:Ifに対応するEnd Ifがありません」と怒られるのは、VBA初心者の「あるある」だ。

これを防ぐためのコツは、If と書いた瞬間に End If もセットで書いてしまうこと。中身の処理を書くのはそのあとだ。外枠を先に作る習慣をつければ、ネスト(入れ子)が深くなっても構造を見失わずに済む。

セルの値によって処理を振り分ける最小単位の構文

「もしAならB、そうでなければC」という処理を作りたいときは、Else を活用する。実務では「もし在庫が10個以下なら発注、そうでなければ現状維持」といった具合だ。

Sub StockCheck()
    If Range("C2").Value <= 10 Then
        Range("D2").Value = "発注要"
    Else
        Range("D2").Value = "在庫あり"
    End If
End Sub

このように Else を挟むことで、条件に当てはまらなかった場合の挙動も制御できるようになる。

Elseを使った二者択一の判断

経理の現場では、振込手数料の負担判定などでこの形をよく使う。例えば、振込金額が3万円以上なら手数料を440円、それ未満なら220円にする、といったケースだ。

VBA If文 条件分岐 - C列の振込金額に基づきD列に手数料が自動入力される様子
C列の振込金額に基づきD列に手数料が自動入力される様子

筆者が以前サポートしたある製造業の経理担当者は、この数千行に及ぶ手数料計算を毎月手計算で行っていた。VBAを導入した結果、ボタン一つで終わるようになり、浮いた時間でより高度な原価分析に注力できるようになったという。

If文を一行で書く「省略記法」の是非

実は、処理が一つだけなら End If を使わずに一行で書くこともできる。

If Range("A1").Value = "" Then Range("A1").Value = 0

ただし、実務レベルのコードではおすすめしない。後から処理を追加したいときに修正が面倒になるし、何より可読性が下がるからだ。将来の自分や、コードを引き継ぐ同僚のために、丁寧な構造で書くことを心がけたい。

条件を満たさない場合の「何もしない」設定

「条件に合致するときだけ処理をし、それ以外はスルーしたい」という場面も多い。その場合は、単に Else を書かずに End If で閉じればよい。
意外と多いのが、「Elseを書かないといけない」という思い込みだ。不要なコードは書かないのが、バグを減らす第一歩となる。

製造業の在庫管理で役立つ「複数条件」のさばき方

現実は「AかBか」の二択で済むほど単純ではない。例えば、株式会社テック工業という架空のメーカーで、部品番号「M-101」の在庫状況を判定するとしよう。
「100個以上なら適正」「50個以上なら注意」「50個未満なら欠品リスク」といった3段階以上の判定が必要になる。

VBA If文 条件分岐 - 部品在庫リストに対して複数条件のIf文を記述する画面
部品在庫リストに対して複数条件のIf文を記述する画面

ここで登場するのが ElseIf だ。

Sub MultiStockCheck()
    Dim stock As Long
    stock = Range("B2").Value

    If stock >= 100 Then
        Range("C2").Value = "適正"
    ElseIf stock >= 50 Then
        Range("C2").Value = "注意"
    Else
        Range("C2").Value = "欠品リスク"
    End If
End Sub

ElseIfを繋げて多段分岐を作る際の注意点

ElseIf を使う際に絶対に守らなければならないルールがある。それは「条件が厳しい(範囲が狭い)順に書く」ということだ。

筆者の研修でよくある失敗例を紹介しよう。
「80点以上はA」「60点以上はB」という判定をしたいときに、先に「60点以上」を判定してしまうケースだ。

' 失敗例
If score >= 60 Then
    result = "B"
ElseIf score >= 80 Then
    result = "A"
End If

このコードに「90点」を入力すると、最初の「60点以上」に合致してしまい、結果は「B」になってしまう。VBAのIf文は、上の条件から順番に判定し、一度合致したらそれ以下の ElseIf は無視されるという特性がある。この順番のミスは、ベテランでも時折やってしまう、まさに「実務でよく見かける」バグの温床だ。

論理演算子「And」と「Or」の使い分け

「AかつB」「AまたはB」という複雑な条件を指定したい場合は、論理演算子を使う。

  • And: すべての条件を満たす場合(例:売上が目標を超え、かつ利益率もクリアしている)
  • Or: いずれかの条件を満たす場合(例:土日である、または祝日である)
  • Not: 条件を満たさない場合(例:空白ではない)
If sales >= 1000000 And profitRate >= 0.1 Then
    Range("D2").Value = "優良案件"
End If

複数のOr条件を効率的に記述する方法

条件が「"A" または "B" または "C" または...」と増えていくと、If文がどんどん長くなってしまう。
If x = "A" Or x = "B" Or x = "C" Then
このような場合は、後述する Select Case 文への書き換えを検討すべきタイミングだ。

経理部の月次締めで「If...Then...Else」を使いこなすコツ

経理部の月次締め作業では、データの不備チェックが欠かせない。例えば、田中さんが担当している経費精算シートで、領収書の有無を確認するマクロを考えてみよう。

「金額が5,000円以上で、かつ備考欄が空欄なら警告を出す」といった処理は、実務で非常に重宝する。

Sub ExpenseCheck()
    Dim i As Long
    For i = 2 To 100
        If Cells(i, 3).Value >= 5000 And Cells(i, 4).Value = "" Then
            Cells(i, 4).Interior.Color = vbYellow
            MsgBox i & "行目の備考が未入力です"
        End If
    Next i
End Sub

ネスト(入れ子)を深くしすぎない工夫

If文の中にIf文を書くことを「ネスト」と呼ぶ。条件が複雑になると 3重、4重と深くなりがちだが、これは極力避けるべきだ。

筆者が過去に引き継いだマクロには、5重にネストされたIf文があった。修正しようにも、どの End If がどの If に対応しているのか判別するだけで1時間以上かかってしまった。

ポイント: ネストが深くなりそうなときは、後述する「早期脱出(Exit Sub)」や「論理演算子での結合」を検討しよう。理想は2階層まで。3階層を超えたらコードの設計を見直すサインだ。

空白セルの判定「IsEmpty」と「""」の違い

経理の現場でよくある失敗に、空白セルの判定ミスがある。
If Range("A1").Value = "" Then と書くのと、If IsEmpty(Range("A1")) Then と書くのでは、厳密には意味が異なる。

"" は長さ0の文字列(空文字)を探すが、IsEmpty はセルが全くの未入力状態かどうかを判定する。
数式が入っていて結果が空になっているセルなどは IsEmpty では True にならない。この違いを理解していないと、「見た目は空なのにマクロが反応しない」という事態に陥る。

エラーを回避する「Ifステートメント」の定石

計算を行う前に、分母が0でないか、あるいはセルにエラー値が入っていないかをIf文で確認する癖をつけよう。
If IsError(Range("A1").Value) Then
これ一行を入れておくだけで、マクロが途中で止まってしまうリスクを劇的に(失礼、大幅に)減らすことができる。

初心者が陥る「End If忘れ」と「インデント」の重要性

VBAを書き始めたばかりの人が最も軽視しがちで、かつ最も重要なのが「インデント(字下げ)」だ。

' 悪い例(読みづらい)
Sub BadExample()
If Range("A1").Value = 1 Then
If Range("B1").Value = 2 Then
MsgBox "OK"
End If
End If
End Sub

' 良い例(構造が明確)
Sub GoodExample()
    If Range("A1").Value = 1 Then
        If Range("B1").Value = 2 Then
            MsgBox "OK"
        End If
    End If
End Sub

Tabキーを使った正しい字下げの習慣

インデントは Tab キーを使って入れる。If文のブロックの中身を一段下げることで、「ここからここまでが条件内の処理だ」ということが一目でわかるようになる。
これは単なる見た目の問題ではない。コードの論理構造を視覚化することで、先ほど述べた End If の書き忘れを物理的に防ぐ効果がある。

VBE(エディタ)の自動構文チェック機能を活用する

VBAの編集画面(VBE)には、構文エラーを自動で教えてくれる機能がある。「ツール」→「オプション」の「自動構文チェック」にチェックが入っているか確認しておこう。
If文の書き間違いがあれば、その行を離れた瞬間に赤文字で警告してくれる。

コメントアウトで条件分岐の意図を残す

「なぜこの条件にしたのか」は、1ヶ月後の自分すら覚えていないものだ。
If sales > 1000000 Then ' キャンペーン適用対象の判定
このように、条件の横に一言コメントを添えておくだけで、メンテナンス性は飛躍的に向上する。

ElseIfとSelect Caseはどちらがメンテナンスしやすいか

条件が4つも5つも重なる場合、ElseIf を繰り返すよりも Select Case 文を使ったほうがスッキリ書ける場合がある。

Select Case文への書き換えタイミング

判定する対象(変数)が一つで、その値によって処理を分けるなら Select Case の出番だ。

Select Case Range("A2").Value
    Case "東京"
        ' 東京支店の処理
    Case "大阪"
        ' 大阪支店の処理
    Case "名古屋"
        ' 名古屋支店の処理
    Case Else
        ' それ以外の処理
End Select

If文よりも見た目が整然としており、後から「福岡支店を追加したい」となったときも、Case "福岡" を一行足すだけで済む。

複数の値をまとめて判定する「Case 1 To 10」

Select Case の強みは、範囲指定が楽なことだ。
Case 1 To 10 (1から10の間)
Case Is >= 100 (100以上)
Case "A", "B", "C" (A、B、Cのいずれか)
このように柔軟な指定ができる。If文で Or を連発するくらいなら、こちらに切り替えたほうが賢明だ。

パフォーマンス(実行速度)の比較

厳密には Select Case のほうが若干高速だと言われているが、通常の事務作業レベルのデータ量(数万件程度)であれば、体感できるほどの差はない。
大切なのは「速度」よりも「読みやすさ」だ。自分が書いたコードを、半年後の自分が読んで3秒で理解できるかどうか。その基準で使い分けるのがプロの視点だ。

営業部の売上ランク付けでよく使う比較演算子の全知識

営業部の佐藤部長から「今期の売上実績に応じて、AからDまでのランクを自動で振ってほしい」と頼まれたとする。
このような評価業務はIf文の得意分野だ。

VBA If文 条件分岐 - 売上実績と達成率が並んだ営業成績表
売上実績と達成率が並んだ営業成績表

「以上」「以下」の境界値を間違えないコツ

実務で最も恐ろしいのは、境界値の判定ミスだ。
例えば「100万円以上はAランク」としたいのに、誤って > 1000000 と書いてしまうと、ちょうど100万円の人がBランクに落ちてしまう。

筆者の経験では、仕様書に「〜超」「〜以上」という言葉が出てきたら、必ずコードの横に >= なのか > なのかをメモするようにしている。この一工夫だけで、集計結果がずれるという致命的なミスを防げる。

文字列の「一部」を条件にするLike演算子

「商品コードが "A" で始まるものだけ処理したい」という場合、= では判定できない。ここで役立つのが Like 演算子とワイルドカード()だ。

If Cells(i, 1).Value Like "A" Then
    ' 処理
End If

この Like 演算子は、請求書の摘要欄から特定のキーワードを探す際などに非常に便利だ。

比較演算子を組み合わせた「範囲指定」の定石

「50以上かつ100以下」という条件を書く際、初心者は 50 <= x <= 100 と書いてしまいがちだが、VBAではこれは通用しない。
If x >= 50 And x <= 100 Then と、二つの式を And で繋ぐ必要がある。これも研修で教えていると非常によく見かける「つまずきポイント」の一つだ。

Microsoft公式ドキュメントから読み解くIf文の制限事項

VBAの If...Then...Else ステートメントには、Microsoftが定めた厳密な仕様がある。
Microsoft公式: If...Then...Else ステートメントによると、ネストの深さに物理的な制限は明記されていないが、メモリのリソースやスタックの制限により、極端に深い入れ子は実行エラーの原因となる可能性がある。

Null値の扱いに注意する

データベースからデータを引っ張ってくる際などに遭遇する「Null(ヌル)」値。これは "" とも 0 とも異なる「値がない」状態だ。
If文で If x = Null Then と書いても、決して True にはならない。判定には IsNull(x) 関数を使う必要がある。公式ドキュメントでも強調されている重要な仕様だ。

ブール型(Boolean)変数を直接評価する

If文の条件式は、最終的に TrueFalse のいずれかになる。
そのため、Dim isComplete As Boolean のような変数がある場合、
If isComplete = True Then と書く必要はなく、
If isComplete Then と書くだけで判定が可能だ。
簡潔なコードは、読み手の負担を減らすことに繋がる。

バリアント型(Variant)による意図しない型変換の罠

変数の型を省略して Variant 型にしていると、If文の判定時に思わぬ自動変換が行われることがある。
数字の 100 と文字列の "100"= で比較した際の結果など、型の整合性には常に気を配るべきだ。可能であれば、比較する前に CLngCStr で型を明示的に変換しておくのが、プロの堅実な書き方と言える。

バージョンを問わず動くコードを書くための注意点

Excel 2016、2019、あるいは Microsoft 365。職場のPC環境は様々だ。しかし、幸いなことに VBA の If文の基本構文は、ここ20年以上変わっていない。

Office 365の新機能との組み合わせ

構文自体は変わらなくても、If文の中で呼び出す「機能」には注意が必要だ。例えば、365で導入された「動的配列」などをIf文の条件で判定しようとすると、古いバージョンのExcelではエラーになる。

Mac版Excelでの挙動の差

筆者の経験では、Windows版で作ったIf文主体のマクロは、Mac版でもほぼそのまま動く。ただし、パスの区切り文字(\ と /)や、一部のActiveXコントロールをIf文で制御しようとすると失敗する。クロスプラットフォームで動かすなら、単純なセルの値判定に留めるのが無難だ。

アドインやライブラリ参照の有無を判定する

特定のライブラリ(参照設定)が必要な処理を行う場合、If文でその参照が有効かどうかを確認してから処理に入るという高等テクニックもある。
そこまでせずとも、On Error Resume NextIf Err.Number <> 0 Then を組み合わせて、エラーが起きた=機能が使えない、と判断させる手法は実務でよく使われる。

実行速度を落とさないための条件判定の順序

10万行のデータに対してIf文を回す場合、ほんの少しの書き方の違いが実行時間に影響を与える。

出現頻度の高い条件を一番上に持ってくる

If文(特に ElseIf)は、上から順番に判定される。
例えば「90%以上が正常、1%未満がエラー」というデータ群を処理する場合、一番上の If に「正常」の判定を持ってくるべきだ。
そうすれば、ほとんどのデータは最初の1回の判定で終了し、下の ElseIf を読み飛ばすことができる。

重い処理(関数)の呼び出しを後回しにする

If CheckFromDatabase(id) = True And x > 0 Then
このような条件式で、CheckFromDatabase が非常に重い(時間がかかる)関数だとする。
この場合、判定の順番を入れ替えて
If x > 0 And CheckFromDatabase(id) = True Then
と書くのが正解だ。
VBA(の古い仕様)では両方を判定してしまうこともあるが、基本的には「軽い条件で先に絞り込む」のがパフォーマンス向上の鉄則だ。

不要なセルアクセスを最小限にする

If文の条件式の中で直接 Range("A1").Value を何度も参照するのは非効率だ。
一度変数に代入してから、その変数をIf文で判定するようにしよう。

' 低速
If Range("A1").Value > 0 Then ...
If Range("A1").Value < 100 Then ...

' 高速
Dim val As Double
val = Range("A1").Value
If val > 0 And val < 100 Then ...

複雑な分岐に関するFAQ

Q: If文のネストは何階層まで許されますか?
A: 技術的な上限は高いですが、実務上は「2階層」までを推奨します。それ以上深くなる場合は、処理を別の Sub プロシージャに分けるか、Select Case を検討してください。

Q: 条件式で大文字と小文字を区別したくないのですが。
A: モジュールの先頭に Option Compare Text と書くか、判定時に UCase 関数で統一してから比較するのが一般的です。
If UCase(Range("A1").Value) = "ABC" Then

Q: 複数の条件すべてに当てはまらない「その他」を必ず書くべきですか?
A: 必須ではありません。しかし、Else (Select Case なら Case Else)を用意して、そこでメッセージボックスを出すようにしておくと、予期せぬデータが紛れ込んだ際にすぐ気づけます。

Q: If文の中で Exit Sub を使ってもいいですか?
A: はい。「エラー条件に合致したら、その時点でマクロを終了する」という使い方は、むしろ推奨されるテクニックです。これを「ガード節」と呼び、コードの可読性を高めます。

VBA If文 条件分岐 - 複雑なIf文を整理してSelect Caseに書き換えたビフォーアフター
複雑なIf文を整理してSelect Caseに書き換えたビフォーアフター

実務の効率を一段階引き上げる書き換えの習慣

If文をマスターした次のステップは、「If文を使わずに済む場所を探す」ことだ。
例えば、セルの値を反対にする(TrueならFalseに、FalseならTrueにする)処理。

' 初心者の書き方
If x = True Then
    x = False
Else
    x = True
End If

' 15年選手(実務家)の書き方
x = Not x

このように、If文を排したスマートな書き方ができるようになると、コードはより短く、バグの入り込みにくいものになる。

しかし、最初からこれを狙う必要はない。まずは泥臭く、自分の頭の中にある判断ロジックを If...Then...Else で忠実に再現することから始めよう。

明日からの実務で、まずは「もしこのセルが空だったら色を塗る」というだけの、ごく小さなIf文から書いてみてほしい。その積み重ねが、いずれ数千行のデータを一瞬で処理する魔法のようなツールへと繋がっていくはずだ。

基本を押さえれば、応用は自然と広がる。

VBA If文 条件分岐 - If文を活用して完成した、条件によって自動で色分けされる月次報告書
If文を活用して完成した、条件によって自動で色分けされる月次報告書

コメント

タイトルとURLをコピーしました