はじめに
VBAで色を表す際は、多くの場合32bit整数であるLong
型で表現される。
RGBの値が決まっていればVBA.RGB
関数で色を作成することが出来るが、その逆の色の数字からRGBを取得する方法は用意されていない。
そこで自分の勉強も兼ねて、色の変換を行うクラスを作成してみた。
コード
Option Explicit
'色からRGBを取得しやすくするためのクラス
'プロパティ
'Color :読み書き:Long :Long型の色
'HexColor :読み :String :Colorの16進数表示
'Red :読み書き:Byte :ColorのR部分
'Green :読み書き:Byte :ColorのG部分
'Blue :読み書き:Byte :ColorのB部分
'メソッド
'なし
Private clsColor As Long
Private clsRed As Byte
Private clsGreen As Byte
Private clsBlue As Byte
Private Sub ChangeColor(iColor As Long)
Select Case iColor
Case 0 To &HFFFFFF 'RGB(0, 0, 0) To RGB(255, 255, 255)
'Next
Case Else
Call Err.Raise(vbObjectError, VBA.TypeName(Me), "0 から 16777215 の間で指定してください")
End Select
Let clsColor = iColor
Dim tmpColor As Long
tmpColor = iColor
Const DIV& = 256
Let clsRed = tmpColor Mod DIV
tmpColor = (tmpColor - clsRed) / DIV
Let clsGreen = tmpColor Mod DIV
tmpColor = (tmpColor - clsGreen) / DIV
Let clsBlue = tmpColor Mod DIV
End Sub
Public Property Get Color() As Long
Let Color = clsColor
End Property
Public Property Let Color(ByVal SetColor As Long)
Call ChangeColor(SetColor)
End Property
Public Property Get HexColor() As String
Let HexColor = VBA.Hex$(clsColor)
End Property
Public Property Get Red() As Byte
Let Red = clsRed
End Property
Public Property Let Red(ByVal iRed As Byte)
Call ChangeColor(VBA.RGB(VBA.CInt(iRed), VBA.CInt(clsGreen), VBA.CInt(clsBlue)))
End Property
Public Property Get Green() As Byte
Let Green = clsGreen
End Property
Public Property Let Green(ByVal iGreen As Byte)
Call ChangeColor(VBA.RGB(VBA.CInt(clsRed), VBA.CInt(iGreen), VBA.CInt(clsBlue)))
End Property
Public Property Get Blue() As Byte
Let Blue = clsBlue
End Property
Public Property Let Blue(ByVal iBlue As Byte)
Call ChangeColor(VBA.RGB(VBA.CInt(clsRed), VBA.CInt(clsGreen), VBA.CInt(iBlue)))
End Property
簡易確認用
上記のクラスをRGBColor
という名前で作成してください。
Sub RGBColorTest_Tekitou()
Dim myCls As RGBColor
Set myCls = New RGBColor
With myCls
Debug.Assert .Color = RGB(0, 0, 0)
.Color = RGB(255, 255, 255)
Debug.Assert .Color = RGB(255, 255, 255)
Debug.Assert .Red = 255
Debug.Assert .Green = 255
Debug.Assert .Blue = 255
Debug.Assert .HexColor = "FFFFFF"
.Blue = 0
Debug.Assert .Color = RGB(255, 255, 0)
Debug.Assert .Red = 255
Debug.Assert .Green = 255
Debug.Assert .Blue = 0
Debug.Assert .HexColor = "FFFF"
.Green = 128
Debug.Assert .Color = RGB(255, 128, 0)
Debug.Assert .Red = 255
Debug.Assert .Green = 128
Debug.Assert .Blue = 0
Debug.Assert .HexColor = "80FF"
On Error Resume Next
.Color = VBA.RGB(255, 255, 255) + 1
Debug.Assert Err.Number <> 0
On Error GoTo 0
End With
Stop
End Sub
作成にあたって
当初は色をを16進数表記変換にして、文字列演算でごり押す方法だった。
途中で256で割れば良いことに気付き、現在の形になった。
RGBの値を算出するタイミングとして、
- RGB参照時に計算を行う
- 色設定時にRGBをまとめて算出する
で迷ったが、フラグ管理が面倒だったため2の方法をとることにした。
また、内部変数のcls~
を直接いじるのをChangeColor
プロシージャにまとめることで、ロジック部分を集約できた。