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

Excel VBA の RGB 関数 — 色が数値になる仕組み(そして BGR の罠)

|

Excel VBA の RGB 関数 — 色が数値になる仕組み(そして BGR の罠)

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)、 FontBorders、タブの色、グラフ系列 — は、同じたぐいの 値を取ります。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 つしかなく(vbBlackvbWhitevbRedvbGreenvbBluevbYellowvbMagentavbCyan)、手早い原色には十分でも、本物のパレットの代わりにはなりません。ブランド がらみのものは何であれ、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 = &H4472C4BGR バグの裏返しです。

どこでも 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.ColorFont.ColorBorders.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 256g = (c \ 256) Mod 256b = c \ 65536 です。Excel は値を BGR として格納するので、赤が下位バイト、青が上位バイト — これは RGB が詰め込んだものをちょうど逆にします。

VBA の vb 色定数とは?

VBA は 8 つの名前付き定数を提供します — vbBlackvbWhitevbRedvbGreenvbBluevbYellowvbMagentavbCyan — それぞれが 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