🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

Excel VBA の Const — マジックナンバーに名前を付ける(そして値がずれない理由)

|

Excel VBA の Const — マジックナンバーに名前を付ける(そして値がずれない理由)

TL;DRConst VAT_RATE As Double = 0.19 は、固定した値に、コンパイル 時に固定される名前を与えます。変数が中身を入れ替えられる箱だとすれば、 定数は塗りつけられたラベルです — どこからでも読めますが、マクロの実行中は どこからも塗り直せません。その不変性こそが肝心な点です:8 つの数式に 散らばったマジックナンバーを、1 つの権威ある出典に変えるのです。Const を 再代入しようとするのはコンパイルエラー(「定数には値を代入できません」)です — そしてそのエラーは、制約ではなく機能です。関連する固定値の一族 (ステータス、列番号)には、多数の別々の Const ではなく Enum を使い ましょう。

Const VAT_RATE   As Double = 0.19          ' 1 か所、1 つの真実
Const MAX_ROWS   As Long = 10000
Const REPORT_TAB As String = "Summary"

Sub ShowRate()
    Debug.Print "VAT is " & VAT_RATE * 100 & "%"   ' -> VAT is 19%
End Sub

どのマクロも、リテラル値であふれています:税率、見出しの行番号、シート名、 しきい値。インラインで打ち込むと、それぞれがマジックナンバーになります — 意味を推測しなければならず、変わったときには値を探し回らなければならない、 むき出しの 0.197 です。Const はその治療薬であり、マクロに施せる 最も安上がりな品質向上の 1 つです。

この記事で学べること

  • マジックナンバーがなぜ保守の罠なのか、そして Const がどうそれを 1 か所で直すのか
  • Const の再代入がなぜコンパイルエラーなのか — そしてそれがなぜ、まさに望むものなのか
  • コンパイル時のルール:Const はリテラルにはなれるが、関数呼び出しやセルの値にはなれない
  • プロジェクト全体で共有する値のための Public Const
  • 多数の Const から 1 つの Enum へ卒業すべきとき

考え方の軸:定数は塗りつけられたラベルで、中身を入れ替える箱ではない

変数と定数は似て見えますが、正反対の振る舞いをします。変数は箱です:値を 入れ、後で別の値に入れ替えられます。定数は、コンパイルする瞬間に値の上に 塗りつけられたラベルです。スコープ内なら誰でもどこからでもラベルを読めます が — コードの実行中は何もそれを塗り直せません。値は凍結されています。

その凍結は、回避すべき制約ではありません。それは、あなたが買っている保証です。 Const VAT_RATE = 0.19 と書くとき、あなたはコンパイラにも次の読み手にもこう 告げています:この数値には 1 つの意味があり、1 か所に住み、あなたの知らない うちに変わることはない、と。定数についての良いことはすべて、その約束から 流れ出ます。

元を取るルール:マジックナンバーはずれるが、定数はずれない

Const が解決する問題がこれです。0.2 — VAT の税率 — が、マクロじゅうの 8 つの異なる数式に直接打ち込まれているとします:

' マジックナンバー 0.2 があちこちに散らばっている — 税率変更は 8 か所すべてを探すこと
gross = net * 1.2
vat   = net * 0.2
' ...あと 6 か所、それぞれにむき出しの 0.2...

さて、税率が 0.19 に変わります。あなたは一つひとつを見つけて編集しなければ なりません。1 か所でも見落とせば、無言の間違った合計が出ます — エラーは なく、ただ数字が合わないだけ、しかもあるレポートでは合い、別のレポートでは 合わない。そして半年後の読み手には、その 0.2 が VAT なのか、割引なのか、 手数料なのか、見当もつきません。

1 つの定数が、それをすべて直します:

Const VAT_RATE As Double = 0.19    ' ここで一度変えれば、すべての箇所が更新される

gross = net * (1 + VAT_RATE)
vat   = net * VAT_RATE

値はちょうど 1 か所に住み、名前がその意味を記録し、税率変更は中途半端に できない 1 行の編集になります。複数回現れるリテラル、あるいは文脈から 意味が明らかでないリテラルは、すべて Const にすべきです。

実は機能であるルール:Const には代入できない

定数を変えようとすると、VBA は拒否します — コンパイル時に、マクロが走り出す 前に:

Const TAX As Double = 0.2

Sub Oops()
    TAX = 0.25       ' コンパイルエラー:定数には値を代入できません
End Sub

初心者は、そのエラーを VBA が意地悪しているのだと読むことがあります。逆です: これはコンパイラが値を決して変わらないと保証していることであり、それこそが あなたが定数を宣言した全理由です。もし再代入したくなっているなら、それは 初めから定数ではなかったのです — 実行時に変わる変数なので、Dim で宣言 しましょう。この区別が、判断のすべてです:この値はマクロの実行中に変わるか? 変わるなら Dim。変わらないなら Const

人を驚かせるルール:Const はコンパイル時に評価される

ラベルはコンパイルするときに塗りつけられるので、定数はコンパイラがすでに 知っているものにしか設定できません:リテラル、または他の定数から組み立てた 式です。関数呼び出し、ワークシートの値、あるいはマクロの実行中に計算される ものにはなれません

' 動く — リテラル、またはリテラルや他の定数の式
Const PI       As Double = 3.14159
Const TWO_PI   As Double = 2 * PI
Const HEADER   As String = "Report — " & "2026"

' 失敗する — 実行時の評価が必要なので、変数でなければならない
Const TODAY    As Date = Date          ' コンパイルエラー:定数式が必要です
Const RATE     As Double = Range("A1").Value   ' コンパイルエラー

値がマクロの実行中にしか分からないなら — 今日の日付、セルの現在の中身、 関数の結果 — それは Const ではなく、実行時に代入する Dim 変数に属します。

スコープ:ローカルな Const と Public Const

ConstDim と同じスコープのルールに従います。Sub の内側に書けば、その 手続きにローカルです。モジュールの一番上に Public を付けて書けば、すべての モジュールが読めるプロジェクト全体の定数になります:

' "Config" というモジュールの、どの手続きよりも上に:
Public Const APP_NAME    As String = "Monthly Close"
Public Const DATA_SHEET  As String = "Raw"
Public Const HEADER_ROW  As Long = 1

規模に応じて効いてくるイディオムは、アプリ全体の定数をすべて収めた 1 つの Config モジュールです — シート名、しきい値、アプリのタイトル — 何かを変える 必要があるとき、見る場所がちょうど 1 か所になるように。手続き固有の定数は ローカルに保ち、本当に共有されるものだけを昇格させましょう。

1 つの値では足りないとき:一族には Enum を使う

関連する定数のグループ — 注文ステータス、列の位置、レポートの種類 — が あるとき、別々の Const の山でも動きますが、読みにくくなります。Enum は それらを 1 つの集合として名付け、1 つの型の下にまとめ、IntelliSense と軽い 型チェックを与えてくれます:

Enum OrderStatus
    Pending = 1
    Paid = 2
    Shipped = 3
    Cancelled = 4
End Enum

Sub Demo()
    Dim s As OrderStatus
    s = Paid
    If s = Cancelled Then Exit Sub
End Sub

目安はこうです:単独の値には Const、まとまって属する関連値の一族には Enum Enum は意図も示します — As OrderStatus と型付けされた パラメーターは、読み手(そしてエディター)に、どの値が正当かを正確に伝えます。

ExcelMaster の活用

定数、スコープの規律、そして Enum は、育っていくマクロを保守可能に保つ 習慣です — そして、本当に気にかけているロジックにたどり着くずっと前から、 プロジェクトごとに背負う諸経費でもあります。

ExcelMaster を使えば、配管を組む代わりにルールを述べられます:「D 列に 19% の VAT を適用、 Cancelled ステータスのものに印を付け、合計を Summary シートに書いて」。それを、 税率とステータス値を 1 か所にまとめた、動くロジックに変えてくれます。だから 変更は、8 つの数式を探し回ることではなく、説明への変更で済みます。制御が 欲しいところでは、これからも手書きのマクロで Const を宣言するでしょう。 日々の作業では、ルールを説明する方が、その裏のマジックナンバーを保守するより 勝るのです。

よくある質問

VBA の定数とは何ですか?

定数とは、コンパイル時に固定され、マクロの実行中は変わらない、名前付きの値です。 Const で宣言します。例:Const VAT_RATE As Double = 0.19。散らばった 「マジックナンバー」を、1 つの名前付きの出典に置き換えるので、値は 1 か所に住み、 その意味は名前によって記録されます。

Const と Dim の違いは何ですか?

Dim変数 — 実行時に値を変えられる箱 — を宣言します。Const定数 — コンパイル時に固定され、再代入できない値 — を宣言します。マクロの実行中に決して 変わらないもの(税率、シート名、しきい値)には Const を、変わるものには Dim を 使いましょう。

実行時に Const を変えられますか?

いいえ。定数に新しい値を代入するのはコンパイルエラー(「定数には値を代入 できません」)であり、その保証こそが定数を使う理由です。マクロの実行中に値を 変える必要があるなら、それは定数ではありません — Dim で変数として宣言 しましょう。

なぜ Const x = Range("A1").Value は失敗するのですか?

Const はコンパイル時に評価されるので、リテラルか他の定数の式にしか設定 できません — 決して、セルの値、関数の結果、Date のような実行時に計算される ものには設定できません。それらには、マクロの実行中に代入する Dim 変数を 使いましょう。

VBA の Enum とは何で、Const の代わりにいつ使うべきですか?

Enum は、関連する名前付き定数の一族を 1 つの型の下に定義します。例:注文 ステータスや列番号。単独の値には複数の Const を使いますが、値が 1 つの集合と してまとまって属するときは Enum に手を伸ばしましょう — それらをグループ化し、 IntelliSense を有効にし、パラメーターをその列挙型として As で型付けして、どの 値が正当かを記録できます。

検証環境

検証環境: Excel 365(Windows 11)、VBA 7.1 — 最終確認 2026-07-31。

関連ガイド: VBA Dim · VBA Data Types · VBA Sub · VBA Function · VBA If Then Else