TL;DR — セルの
.Colorは色の名前ではありません。1 つの数値 です。RGB(r, g, b)は、 3 つのチャンネル(各 0 から 255)をその数値に詰め込む関数です。落とし穴はその順序です。RGBは 赤が下位、青が上位(r + g*256 + b*65536)で組み立てます。これは Web の 16 進数とは逆 です。だから#4472C4を.Color = &H4472C4としてそのまま貼ると、赤と青が入れ替わり、違う色 になります。色は常にRGB(...)で組み立て、どうしても 16 進数を使うなら、バイトが逆さまだと 覚えておきましょう。
' RGB は 3 つのチャンネルを 1 つの Long に詰め込む:
Range("A1").Interior.Color = RGB(68, 114, 196) ' 特定の青、どのマシンでも正しい
' Web の 16 進数 #4472C4 は同じ青 - でも生のまま貼らないこと:
Range("A2").Interior.Color = &H4472C4 ' 誤り: これは #C47244 (赤と青が入れ替わる)
Range("A3").Interior.Color = RGB(&H44, &H72, &HC4) ' 正しい: 16 進数をチャンネルに分ける
Excel VBA のあらゆる色プロパティ — セルの塗り(Interior)、
Font、Borders、タブの色、グラフ系列 — は、同じたぐいの
値を取ります。24 ビットの数値です。RGB はそれを組み立てる方法で、その数値が 何なのか を
理解すれば、「色が近いけれど違う」というひとそろいのバグが説明できます。とりわけ、Web サイトや
ブランドガイドの 16 進コードが絡むときにです。
この記事で学べること
- 考え方の軸 —
.Colorは 1 つの数値であり、RGBはその詰め込み係 - 誰もがはまる罠 — 数値は
BGRで格納され、Web の 16 進数とは逆順 vb*の色定数、そしてそれがバイト順について明かすこと- 色を読み戻し、赤・緑・青に分解する
- 塗り・フォント・罫線・グラフで色モデルが同一である理由
- 判断 — パレットは名前付き定数として一度だけ定義する
考え方の軸:1 つの数値、3 つのチャンネル
画面上の色は 3 つのダイヤルです。赤がどれだけ、緑がどれだけ、青がどれだけ、それぞれ 0 から
255 までです。RGB(r, g, b) はその 3 つのダイヤルを、Excel がオブジェクトに格納する 1 つの整数
(Long)に畳み込みます。RGB(0,0,0) は黒(全ダイヤルがオフ)、RGB(255,255,255) は白(全オン)、
RGB(255,0,0) は純粋な赤です。色そのものに不思議なところはありません — 驚きはすべて 3 つの
ダイヤルがどう 1 つの数値に詰め込まれるか にあり、そこにバグが住んでいます。
最も大事なルール:数値は RGB ではなく BGR
RGB が実際に使う式はこれです。
RGB(r, g, b) = r + g * 256 + b * 65536
よく読んでください。赤が最下位バイト、青が最上位バイトです。 16 進数では、格納される値は
&HRRGGBB ではなく &HBBGGRR です。#4472C4 のような Web カラーは、RGB 順で赤 44、緑 72、
青 C4 を意味します — でも Excel は BGR 順で格納します。だから Web の 16 進数を .Color に
そのまま貼った瞬間、赤と青のチャンネルを入れ替えたことになります。
Range("A1").Interior.Color = &H4472C4 ' Excel はこれを BGR と読む: R=C4, G=72, B=44 -> オレンジがかった赤
これは丸め誤差ではありません。まったく別の色であり、CSS では問題なかったブランドカラーが
「マクロでは違って見える」第 1 位の理由です。確実な直し方は、Excel に詰め込み済みの 16 進数を一切
渡さないこと — 3 つのチャンネルを渡し、RGB に詰め込ませることです。
Range("A1").Interior.Color = RGB(&H44, &H72, &HC4) ' 正しい: チャンネルは正しいダイヤルに収まる
どうしてもリテラルを格納しなければならないなら、&HC47244 へ反転させます。でも 16 進数を
RGB(...) に分けるほうが明快で、逆さまにしようがないので、それが身につける価値のある習慣です。
vb 定数と、それが証明すること
VBA には名前付きの色定数がいくつか付いています。原色には便利で、しかもバイト順を静かに 裏づけます。
Debug.Print vbRed ' 255 = RGB(255, 0, 0) -> 赤は下位バイト
Debug.Print vbGreen ' 65280 = RGB(0, 255, 0)
Debug.Print vbBlue ' 16711680 = RGB(0, 0, 255) -> 青は上位バイト
vbRed = 255 が手がかりです。もし赤が 上位 バイトなら、純粋な赤は 16711680 になるはずです。
これらの定数は 8 つしかなく(vbBlack、vbWhite、vbRed、vbGreen、vbBlue、vbYellow、
vbMagenta、vbCyan)、手早い原色には十分でも、本物のパレットの代わりにはなりません。ブランド
がらみのものは何であれ、RGB(...) で綴りましょう。
色を読み戻して分解する
.Color を読むと、詰め込まれた Long が返ります。3 つのチャンネルを取り出すには、詰め込みを
逆にします — 赤は余り、青は最上位です。
Dim c As Long: c = Range("A1").Interior.Color
Dim r As Long, g As Long, b As Long
r = c Mod 256
g = (c \ 256) Mod 256
b = c \ 65536
Debug.Print r, g, b ' 元の 3 つのチャンネル
比較についての実践的な要点はこうです。格納された .Color を、自分が打った生の 16 進数リテラルと
比べては決していけません — Excel と同じように詰め込む RGB(...) と比べます。
If .Interior.Color = RGB(68,114,196) のテストは正しく、If .Interior.Color = &H4472C4 は BGR
バグの裏返しです。
どこでも 1 つの色モデル
これを一度学ぶ見返りは、色が現れるどこでも 同じ 数値だということです。同一の RGB(...) 値が
次のすべてで効きます。
ws.Range("A1").Interior.Color = RGB(68, 114, 196) ' 塗り
ws.Range("A1").Font.Color = RGB(255, 255, 255) ' テキスト
ws.Range("A1").Borders.Color = RGB(0, 0, 0) ' 罫線
ws.Tab.Color = RGB(68, 114, 196) ' シートタブ
オブジェクトごとに学び直す色の形式はありません。塗り、フォント、罫線、タブ、グラフ系列 —
すべてが 1 つの 24 ビット Long を取ります。だから詰め込みを一度正しくやる価値があります。
直し方と習慣が、オブジェクトモデルの色を持つすべてに転用できるのです。(古い ColorIndex
プロパティは例外です — この数値ではなくパレットのスロットです。
VBA ColorIndex を参照。)
判断:パレットは一度だけ名前を付ける
RGB(255, 242, 204) を百行にばらまくと、レポートは微妙に違う 3 つの「ゴールド」を抱え込むことに
なります。パレットはモジュールの先頭で一度だけ、名前付き定数として定義しましょう — そうすれば
色には名前が付き、1 か所に住み、変更も造作ありません。
Private Const CLR_HEADER As Long = 4759559 ' RGB(68,114,196) を一度だけ詰め込む
Private Const CLR_WARN As Long = 13551615 ' RGB(255,199,206)
あるいは小さなヘルパーの中で RGB(...) のまま保っても構いません。どちらにせよ、ルールは
定数全般を統べるのと同じです。何かを意味する値には名前を付けるべきで、
打ち直すものではありません。 RGB で組み立て、1 か所に格納すれば、詰め込み済みの 16 進数を手で
書くことがないので、BGR の罠は決して噛みつけません。
ExcelMaster の活用
BGR の反転は本当に厄介なバグです。コードは正当で、色が ただ間違っている だけだからです —
オレンジとして出荷されるブランドの青、生の 16 進数を BGR 値と照合しているせいで決して一致
しない比較。何もエラーにならないからこそ、半日を溶かします。
ExcelMaster なら、色を実際に手元に
ある形で渡せます。「#4472C4 を使って」「うちのブランドグリーンにして」「255, 242, 204」と言えば、
チャンネルを正しいダイヤルに収めた RGB(...) を書き、バイト反転した 16 進数は決して書きません。
「ヘッダーの色に一致するセルをハイライトして」と頼めば、生のリテラルではなく RGB(...) と比較
するので、一致が実際に効きます。色を再利用するときは、それを名前付き定数へ引き上げます。ブックも
コードもあなたの手元に残り、チャンネルが入れ替わった半日だけを省けます。
よくある質問
VBA で RGB 関数はどう動く?
RGB(red, green, blue) は、各 0 から 255 の 3 つのチャンネルを取り、Excel が色として使う 1 つの
Long 値を返します。RGB(255, 242, 204) は淡いゴールドです。内部では red + green*256 + blue*65536
を計算するので、その数値は 24 ビットの色で、どの色プロパティにも代入できます — Interior.Color、
Font.Color、Borders.Color などです。
VBA で 16 進コードを使うと色が違うのはなぜ?
Excel は色を BGR 順(青が上位バイト、赤が下位バイト)で格納し、これは #RRGGBB のような Web の
16 進数とは逆だからです。.Color = &H4472C4 の代入はそれを BGR として読み、赤と青を入れ替え
ます。代わりに 16 進数をチャンネルに分けましょう — .Color = RGB(&H44, &H72, &HC4) — か、リテラルを
&HC47244 へ反転させます。
VBA で 16 進の色を RGB に変換するには?
16 進数を 3 つのバイト対に分け、RGB に渡します。#4472C4 なら RGB(&H44, &H72, &HC4) と書きます。
これで各チャンネルが正しいダイヤルに収まり、詰め込み済みの 16 進数を .Color に直接代入したときに
はまる BGR バイト順の罠を避けられます。
色から赤・緑・青の値を取り出すには?
.Color から詰め込まれた Long を読み、分解します。r = c Mod 256、g = (c \ 256) Mod 256、
b = c \ 65536 です。Excel は値を BGR として格納するので、赤が下位バイト、青が上位バイト —
これは RGB が詰め込んだものをちょうど逆にします。
VBA の vb 色定数とは?
VBA は 8 つの名前付き定数を提供します — vbBlack、vbWhite、vbRed、vbGreen、vbBlue、
vbYellow、vbMagenta、vbCyan — それぞれが RGB(...) 値に等しく(vbRed = 255 = RGB(255,0,0))
です。原色には便利ですが、特定の色やブランドカラーには RGB(r, g, b) を使い、3 つのチャンネル
すべてを自分で制御しましょう。
検証環境
動作確認: Excel 365 (Windows 11), VBA 7.1 — 最終確認 2026-09-08。
関連ガイド: VBA ColorIndex · VBA Cell Color · VBA Font · VBA Conditional Formatting · VBA Constant
