テクニカル雑記帳です
【VBA】ColorIndexは色によってユニークな値ではなかった話
こんな関数を作って同じ背景色の合計を出そうとしました。
'## 背景色が合致したセルをカウントする ##
Function CountColor(計算範囲, 条件色セル)
Application.Volatile
CountColor = 0
For y = 1 To 計算範囲.Columns.Count
For x = 1 To 計算範囲.Rows.Count
If 計算範囲.Rows(x).Columns(y).Interior.ColorIndex = 条件色セル.Interior.ColorIndex Then
CountColor = CountColor + 1
End If
Next
Next
End Function
これ、同系色?は同じ色としてカウントするみたい。(正確なルールがよく分からない)
取得できるColorIndexには皆さん気をつけてくださいませ・・・
ちなみに確認するために作った関数。
'## 背景色のColorIndexを取得する
Function GetColorIndex(対象セル)
Application.Volatile
GetColorIndex = 対象セル.Interior.ColorIndex
End Function
この画像を見ていただくと分かるのですが、E6~H6のColorIndexをE7~H7に出しました。
見事に同じ・・・
これのせいで計算が間違っているように見えたみたい。一定の透明度?濃度?からさがるとColorIndexが共通しちゃうのかな?原因は不明です。(いつか調査するかも)
【調べました】ColorIndex()
は古いExcelの時のメソッドらしく新しめのExcelの色合いには対応していないそう。
代わりに使うのが Color()
で、これはRGB値をlong型で返してくれる。
このlong値は「B・G・R」の順に「bbbbbbbbggggggggrrrrrrrr(1文字1bit)」で返ってくるので、R,G,Bの形にするには計算の必要がある。
なので、
Sub Sample()
Dim n As Long
Dim r As Byte
Dim g As Byte
Dim b As Byte
# 対象セルの色をLong値で取得
n = 対象セル.Interior.Color
# それぞれRGBごとに計算
r = n \ 256 ^ 0 Mod 256 # 0~16,777,215の範囲の値(R,G,B) % 256
g = n \ 256 ^ 1 Mod 256 # 256~16,777,215の範囲の値(G,B) % 256
b = n \ 256 ^ 2 Mod 256 # 65,536~16,777,215の範囲の値(B) % 256
# #rrggbb の形で出力
MsgBox "#" & r & g & b
End Sub
「0~16,777,215の範囲の値」とか言っているのは、10進数/16進数 で見た時に各値が持つ範囲が以下のようになるので算出している。 R:0~255/000000~0000FF G:256~65,535/0000FF~00FFFF B:65,536~16,777,215/00FFFF~FFFFFF
簡単に言うと、532円を100の位、10の位、1の位に分けているようなもの。
※「\」とは、割り算の商・整数部だけを計算する演算子で、JavaScriptで言うところの「parseInt()」↓と同じ
var ans = parseInt(9 / 2); // ans = 4
※「Mod」とは、割り算での余りの数を計算するための演算子で、JavaScriptで言うところの「%」↓と同じ
var ans = 9 % 2 // ans = 1