【入門編】定数(Const)と列挙型(Enum)によるマジックナンバーの撲滅 – Excel VBA解析バイブル

スポンサーリンク

「謎の数字」とサヨナラしよう!ConstとEnumで実現するプロ品質のVBAコード設計入門

こんにちは!VBAの基本文法を覚え、マクロの自動記録から一歩踏み出したあなた。毎日の業務効率化、本当にお疲れ様です!

順調にコードが書けるようになってくると、次にぶつかるのが「過去に書いた自分のコードの意味が分からない」「シートの列を1行挿入したらマクロが動かなくなった」という壁ではありませんか?

例えば、こんなコードに見覚えはありませんか?

‘ 1ヶ月後の自分が絶望するコードの例
If Cells(i, 5).Value = 2 Then
Cells(i, 8).Value = 1
End If

「`5`列目ってなんだっけ?」「`2`って何のステータスだっけ?」……これがプログラミングの世界で忌み嫌われる「マジックナンバー(呪文のような謎の数字)」です。

今回は、このマジックナンバーをコードから完全に撲滅し、劇的に読みやすく、修正に強いコードへ生まれ変わらせる2大ツール「`Const`(定数)」「`Enum`(列挙型)」の完全解説をお届けします!

ここをマスターできれば、あなたのVBAスキルは「脱・初心者」どころか「プロの現場レベル」へ一気にステップアップしますよ。一緒に楽しく学んでいきましょう!

1. なぜ「マジックナンバー」は危険なのか?

プログラミングにおける「マジックナンバー」とは、コード内に直接書き込まれた、意味の分からない数値のことです。

なぜこれが危険なのか、簡単な図解でイメージしてみましょう。

【マジックナンバーが潜むコード】
Cells(i, 4).Value = 3 <--- 「4列目」って?「3」って何の状態? │ ├── 現場の運用変更!「C列に新しい項目を追加したよ」 ▼ Cells(i, 4) は「D列」を指していたのに、ズレてしまう! コード中に散らばる「4」を全部「5」に手作業で修正……(修正漏れでバグ発生) マジックナンバーがもたらす害悪は主に3つあります。 1. 可読性の低下:書いた本人すら、数日後には意味を忘れる。
2. 保守性の低下:仕様変更(列の追加など)があった際、該当する数字をすべて手作業で探して直す必要がある。
3. バグの温床:打ち間違い(タイポ)があっても、VBAのエラーチェック(コンパイル)をすり抜けてしまう。

この問題をスマートに解決するのが`Const``Enum`です。

2. 一つの値を大切に守る「Const(定数)」

まずは基本となる`Const`(定数)から解説します。

Constとは?

「定数(Constant)」とは、一度決めたら後から値を変更できない変数のようなものです。プログラム中で変わることのない「固定の値」に名前を付けて保管します。

書き方とスコープ(有効範囲)

‘ モジュールレベル(このモジュール全体で使う定数)
Private Const TAX_RATE As Double = 0.1 ‘ 消費税率 10%

Sub CalculatePrice()
‘ 手続きレベル(このSubプロシージャ内だけで使う定数)
Const DISCOUNT_FEE As Long = 500 ‘ 割引額 500円

Dim rawPrice As Long
rawPrice = 10000

‘ 意味がひと目でわかる!
Dim finalPrice As Long
finalPrice = (rawPrice – DISCOUNT_FEE) (1 + TAX_RATE)

Debug.Print “支払金額: ” & finalPrice
End Sub

💡 長期運用を支えるプロの極意:命名規則

`Const`を使うときは、一目で「これは定数だ!」とわかるようにすべて大文字+スネークケース(単語間をアンダーバーで繋ぐ)で命名するのが標準的なプロの作法です。(例: `MAX_ROW_COUNT`, `DEFAULT_SHEET_NAME`)

3. 関連する数字をスマートに束ねる「Enum(列挙型)」

`Const`を覚えると、「じゃあ1列目は`COL_ID`、2列目は`COL_NAME`、3列目は`COL_PRICE`と定数をたくさん作ればいいのかな?」と思うかもしれません。

間違いではありませんが、関連する複数の選択肢や連番を扱うなら「`Enum`(列挙型)」が圧倒的にエレガントです!

Enumとは?

`Enum`(Enumerationの略)は、関連する整数値のグループにまとめて名前をつける機能です。

例えば、「処理ステータス(未処理=1、処理中=2、完了=3、エラー=9)」や「ワークシートの列番号」などをグループ化するのに最適です。

‘ 処理ステータスを列挙型として定義
Public Enum TaskStatus
StatusPending = 1 ‘ 未処理
StatusProcessing = 2 ‘ 処理中
StatusCompleted = 3 ‘ 完了
StatusError = 9 ‘ エラー
End Enum

なぜEnumが最強なのか?「IntelliSense(自動補完)」の魔法

`Enum`を定義しておくと、コードを書くときに入力候補がドロップダウンで自動表示(IntelliSense)されるようになります!

If currentStatus = TaskStatus. [★ここに候補がズラリと表示される!]
│ StatusPending
│ StatusProcessing
│ StatusCompleted
└ StatusError

これにより、記憶に頼らずコードが書け、スペルミスや存在しない数値の代入を未然に防ぐことができるのです。これがプロ開発者にとって最大のメリットです。

4. 【実践】Enumを使って「劇的に美しいコード」を書こう!

それでは、実際の業務でよくある「受注データのステータス更新マクロ」を例に、ビフォー&アフターを見てみましょう。

❌ 改善前:マジックナンバーだらけの読みにくいコード

‘ 【NG例】何をやっているのかサッパリ分からない…
Sub ProcessOrders_Bad()
Dim lastRow As Long
lastRow = Cells(Rows.Count, 1).End(xlUp).Row

Dim i As Long
For i = 2 To lastRow
‘ 4列目(ステータス)が 1(受付済み)なら
If Cells(i, 4).Value = 1 Then
‘ 5列目(金額)が 10000 以上なら
If Cells(i, 5).Value >= 10000 Then
‘ 4列目を 2(承認)にする
Cells(i, 4).Value = 2
Else
‘ 4列目を 3(保留)にする
Cells(i, 4).Value = 3
End If
End If
Next i
End Sub

⭕ 改善後:Enumを活用した超・高可読性コード

標準モジュールの上部に`Enum`を宣言し、それを使って書き直します。

Option Explicit

‘ — 列番号の定義 —
‘ Excelシートの列の位置を名前で管理します
Public Enum OrderCol
ColID = 1 ‘ A列: 注文ID
ColCustomerName ‘ B列: 顧客名 (自動的に 2 になる)
ColOrderDate ‘ C列: 注文日 (自動的に 3 になる)
ColStatus ‘ D列: ステータス (自動的に 4 になる)
ColAmount ‘ E列: 金額 (自動的に 5 になる)
End Enum

‘ — ステータス値の定義 —
‘ 業務上の状態を表す数字に意味を与えます
Public Enum OrderStatus
StatusReceived = 1 ‘ 受付済み
StatusApproved = 2 ‘ 承認
StatusPending = 3 ‘ 保留
StatusRejected = 9 ‘ 却下
End Enum

‘ 【OK例】まるで日本語の仕様書を読んでいるかのようなコード!
Sub ProcessOrders_Good()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(“受注リスト”)

Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, OrderCol.ColID).End(xlUp).Row

Dim i As Long
For i = 2 To lastRow

‘ 現在のステータスを取得
Dim currentStatus As OrderStatus
currentStatus = ws.Cells(i, OrderCol.ColStatus).Value

‘ ステータスが「受付済み」の場合のみ処理
If currentStatus = OrderStatus.StatusReceived Then

Dim amount As Long
amount = ws.Cells(i, OrderCol.ColAmount).Value

‘ 金額条件によってステータスを変更
If amount >= 10000 Then
ws.Cells(i, OrderCol.ColStatus).Value = OrderStatus.StatusApproved
Else
ws.Cells(i, OrderCol.ColStatus).Value = OrderStatus.OrderStatus.StatusPending
End If

End If

Next i

MsgBox “処理が完了しました!”, vbInformation
End Sub

どうでしょうか?
コメントがなくても、コードそのものが「何をしているのか」を雄弁に物語っていますよね!

もし将来、「C列とD列の間に新しい列が挿入された」としても、`OrderCol`の定義を1箇所修正するだけで、プログラム全体が正しく動作し続けます。

5. 陥りやすい罠とプロのワンポイントアドバイス

ここで、初心者がよくハマるポイントと、ワンランク上の知識をお伝えします。

罠1:Enumの数値は「省略すると自動インクリメント」される

`Enum`で数値を明示しない場合、直前の値に `+1` された数値が自動的に割り振られます(一番最初を省略すると `0` から始まります)。

Public Enum Example
ValA ‘ 0 になる
ValB ‘ 1 になる
ValC = 10
ValD ‘ 11 になる (10 + 1)
End Enum

シートの列番号(1始まり)として使う場合は、最初の要素に `= 1` を明示しておくと安心です!

罠2:VBAのEnumは内部的には「Long型(整数)」

VBAの`Enum`は内部的に4バイトの整数(`Long`型)として扱われます。
そのため、文字列(`”Pending”` など)を`Enum`に割り当てることはできません。文字列に意味を持たせたい場合は `Const` を使いましょう。

まとめ:ここをクリアすれば、Excel VBAの基本はバッチリです!

今回は、コードからマジックナンバーを撲滅するための`Const``Enum`について解説しました。

  • 単一の変更されない値には ⇒ `Const` を使う(例:税率、ファイルパス)
  • 関連する複数の数値グループには ⇒ `Enum` を使う(例:列番号、ステータス区分)

これらを意識して書かれたコードは、読みやすいだけでなく、仕様変更にも強い「堅牢な資産」になります。

最初は「毎回定義を書くのが少し面倒だな」と思うかもしれません。ですが、未来の自分や同僚がそのコードを開いたとき、「なんて読みやすいコードなんだ!」と感動すること間違いなしです。

ぜひ、今日書くマクロから「謎の数字」を無くしていきましょう。応援しています!

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