ColorプロパティとRGB関数について


Colorプロパティ

Excel 2003まででお馴染みのColorIndexプロパティは、あらかじめ56色が登録されている色パレットから、何番目の色を使うかというプロパティです。たとえば、標準の色パレットでは、3番に赤が登録されていますので、ColorIndexプロパティに3を設定すると、そこは赤くなるという仕組みです。

対してColorプロパティは何を設定するプロパティでしょうか。ヘルプには次のように書かれています。

オブジェクトに応じて適用するを設定します。色は、RGB関数によって作成された値です。

Colorプロパティには「色」を設定すると。その設定する「色」は、RGB関数によって作成すると。そういうことです。

では、RGB関数とは何でしょう。これもヘルプを見てみます。

色のRGB値を表す長整数型 (Long) の値を返します。
構文
RGB(red, green, blue)
red:RGBのR(赤)の割合を0~255の整数で指定します
green:RGBのG(緑)の割合を0~255の整数で指定します
blue:RGBのB(青)の割合を0~255の整数で指定します

一般的に色は「赤」「緑」「青」の組み合わせで表現されます。

それぞれの濃さを、仮に0から255までの数字で表すなら、

赤:255

緑:0

青:0

は、もちろん赤です。そして、

赤:255

緑:255

青:0

は、黄色ですね。では、

赤:112

緑:48

青:160

は何色でしょう。これは、Excel 2007以降で使用可能になった「紫」です。

これをRGB関数で表すと「RGB(112, 48, 160)」となります。

RGB関数は、こうした色の割合を数値で返します。その計算方法は次の通りです。

上の「紫」でしたら「112+48×256+160×256×256」で「10498160」となります。

Sub Sample1()
    MsgBox RGB(112, 48, 160)
End Sub

このように、RGB関数を使うと、すべての色を数値で表すことができます。そして、このRGB関数で計算した色を表す数値(これをRGB値といいます)によって色を設定するプロパティが、Colorプロパティです。

このRGB関数とColorプロパティは、Excel 2003以前のExcelでも使用可能でした。可能でしたが、Excel 2003までは、ワークシート上で表示できる色は56色だけです。

Excel 2003までも、RGB関数とColorプロパティで中間色を指定できたのですが、実際に使用できる色(表現できる色)は、色パレットに登録された56色でした。もし、色パレットに登録されていない色を指定した場合は、最も近い色とExcelが判断した色に置き換えられました。ちょっと試してみましょう。Excel 2003で、セルの背景色に中間色を指定してみます。

次のコードは、RGB関数に指定する引数を5ずつ増加させています。

Sub Sample2()
    Dim i As Long, j As Long
    For i = 0 To 255 Step 5
        j = j + 1
        Cells(j, 1).Interior.Color = RGB(i, 0, 0)
        Cells(j, 1) = i & ", 0, 0"
        Cells(j, 2).Interior.Color = RGB(255, i, 0)
        Cells(j, 2) = "255, " & i & ", 0"
        Cells(j, 3).Interior.Color = RGB(0, 255, i)
        Cells(j, 3) = "0, 255, " & i
    Next i
End Sub

【Excel 2003の実行結果】

もちろんこれは、セルだけの話ではなく、グラフの塗りつぶし色などでも同様です。

Excel 2007では、グラフィックエンジンが一新し、ワークシート上で表現できる色数が増えました。

RGB関数やColorプロパティで、淡い中間色を指定することが可能になったのです。

【Excel 2007の実行結果】

このように、表示できる色の種類が増えたため、Excel 2007では、それまでのColorIndexプロパティに代わってColorプロパティが積極的に使用されるようになりました。たとえば、セルの背景色を赤色に塗りつぶす操作をマクロ記録してみましょう。

Sub Macro1()
    ''Excel 2007のマクロ記録
    With Selection.Interior
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .Color = 255
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With
End Sub

ちなみに、Excel 2003までは次のようになります。

Sub Macro1()
    ''Excel 2003のマクロ記録
    With Selection.Interior
        .ColorIndex = 3
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
    End With
End Sub

-16776961 とは?

ところで、マクロ記録といえば、ひとつ不思議なことがあります。

Excel 2007で、文字色を赤色にする操作をマクロ記録してみます。

Sub Macro2()
    ''Excel 2007で文字色を赤にした
    With Selection.Font
        .Color = -16776961
        .TintAndShade = 0
    End With
End Sub

この「-16776961」とは何でしょう。

Colorプロパティには、RGB関数で計算したRGB値を設定します。RGB関数が計算するRGB値は、上の計算方法で分かるように、決してマイナスにはなりません。赤は、RGB(255, 0, 0)です。これを数値に変換すると「255」です。「-16776961」ではありません。しかし、このマクロ記録されたコードをそのまま実行すると、確かに文字色が赤色になります。もちろん、変な数値が記録されるのは赤だけではありません。文字色を青にする操作をマクロ記録すると、次のようになります。

Sub Macro2()
    ''Excel 2007で文字色を青にした
    With Selection.Font
        .Color = -65536
        .TintAndShade = 0
    End With
End Sub

RGB(255, 0, 0)のRGB値が「-16776961」と記録されるのは、次のような理由と推測できます。

まず、赤を表すRGB(255, 0, 0)のRGB値を計算してみます。

ここからは、Windows付属の電卓を使いましょう。

この「255」を16進表示に切り替えます。

緑と青の数値がそれぞれ0ですから、ただ「FF」となっていますが、緑と青の0を合わせると、つまりこういうことです。

ヘルプによると、RGB関数は長整数型(Long)を返します。Longは4バイトですから上図「00 00 FF」では1バイト足りません。もう1バイト「FF」を追加します。

これを10進で表したのが「-16776961」です。

いわゆる、32ビットの符号付き倍長整数型なのですが、マクロ記録で記録されるColorプロパティでは、上位バイトに「FF」が追加されて記録されます。赤はRGB(255, 0, 0)で、それを10進で表すと「255」なのですから、できれば「255」と記録して欲しいですよね。セルの塗りつぶしをマクロ記録したときなどには「255」が記録されることから、文字色の設定でも「255」と記録されるのが自然だと思います。

なお、この記録されたコードをそのまま実行すると、セルの文字色は意図したとおり赤色になります。上位バイトの「FF」は無視される、というか、ここにどんな数値が指定されていても、255のRGB値と認識されるようです。

Sub Sample3()
    With Range("A1")
        .Font.Color = CLng("&H000000FF")
        .Offset(0, 1) = .Font.Color
    End With
    With Range("A2")
        .Font.Color = CLng("&H880000FF")
        .Offset(0, 1) = .Font.Color
    End With
    With Range("A3")
        .Font.Color = CLng("&HFF0000FF")
        .Offset(0, 1) = .Font.Color
    End With
End Sub

いずれにしても、ColorプロパティにはRGB関数で計算したRGB値を指定するのがセオリーです。マクロ記録で変な数値が記録されたからとって、その変な数値をそのまま使うのではなく

Range("A1").Font.Color = RGB(255, 0, 0)    ''赤にする

みたいにするのがいいでしょう。