以下の内容はhttps://www.limecode.jp/entry/class/rgb-calculatorより取得しました。


色(RGB値)の操作を補助するクラスを作る

今回はクラスモジュールづくりのサンプルとして、
色の操作を補助するクラス」を作ってみました。

Property Get & Let プロシージャの勉強にピッタリな題材なので、
クラスの練習がてら、コードを眺めて&書いてみてください。


もちろん色操作が必要なマクロに組み込んでご活用もいただけます。

クラスモジュールの設計(目的コード)

クラスモジュールは「コードを整理整頓するための道具」ですので、
どんなふうに整理整頓するかを先に決めておく必要があります。


目的を知ってからの方がコードが読みやすくなりますので、
先に目的とする標準モジュールの記述から解説します。

今回目指すのはこんなコード↓が書けるクラスです。

Dim clsRGB As New ClassRGB操作

' ① RGB値をいれるとR,G,Bを個別に見ることができる
clsRGB.RGB = RGB(220, 160, 120) ' RGB値に代入
Debug.Print clsRGB.R ' ← 220 が表示される


' ② 入っているRGB値のR,G,Bを個別に変更することができる
clsRGB.R = 240 ' R値に代入
Debug.Print clsRGB.RGB ' = 7905520 (RGB(240,160,120)の値)
Debug.Print clsRGB.RGBテキスト ' = 「240,160,120」
    ' ※ カンマ区切りテキストで表示するプロパティも用意


' ③ セルとリンクさせることができる
Set clsRGB.リンクするセル = Range("A1")
               ' ↑ 同時にRGB値にセル背景色が入る
clsRGB.R = 255 ' ← 同時にセルの背景色が変わる


' ④ 同じように図形ともリンクできる
Set clsRGB.リンクするShape = ActiveSheet.Shapes("TextBox 2")
clsRGB.G = 100 ' ← 同時にテキストボックスの背景色が変わる


' ⑤ リンク先を「背景色/フォント色」で切り替え可能
clsRGB.is文字色をリンクする = True
    ' ↑ 以降のコードではセル・図形のフォント色を設定する

Set clsRGB.リンクするセル = Range("A1")
clsRGB.RGB = RGB(255, 0, 0) ' ← セルの文字色が赤になる

なかなか便利そうなクラスですね。

  • ① RGB値を入れたら裏でR値,B値,G値も計算されている
  • ② 逆にR値をいじっても、裏でRGB値が再計算される
  • ③④ RGB値を変更するとセルや図形が連動して着色される

こんな風に「代入と同時に裏で他の変数も更新したい」場合こそ、
Propertyプロシージャの出番になります。


先にクラス内の「R」に関連するコードだけ抜粋しますとと、

' 裏で動く変数(_をつけるのが一般的)
Private R_ As Long

' 表で「R」を読み取るときはR_をそのまま出す
Property Get R() As Long
    R = R_
End Property
    ' ↑ Debug.Print cls.R の時はこれが呼ばれる

' 表で「R」を書き換えたときに、裏で他の変数もいじる
Property Let R(代入値 As Long)

    R_ = 代入値 ' とりあえず代入された値を裏のR_に入れる
    RGB_ = VBA.RGB(R_, G_, B_) ' RGB値を再計算
    Call リンクするオブジェクトを着色する ' セルや図形も着色

End Property
    ' ↑ cls.R = 100 などの代入文でこれが呼ばれる

' 裏の「R_」は「RGB」を変更したときにも書き換える
Property Let RGB(代入値 As Long)

    RGB_ = 代入値
    R_ = RGB_ Mod 256 ' RGB値の代入時に裏のR_も再計算
    G_ = Int(RGB_ / 256) Mod 256
    B_ = Int(RGB_ / 256 / 256)
    
    Call リンクするオブジェクトを着色する

End Property
   ' ↑ cls.RGB = ○○ でRの値も変わる機能がこれ

こんな実装をしています。

これを踏まえて、コード全体を見てみてください。

クラスモジュールのソースコード

Option Explicit

Private リンクするセル_ As Range
Private リンクするShape_ As Shape
Public is文字色をリンクする As Boolean

Private RGB_ As Long
Private R_ As Long
Private G_ As Long
Private B_ As Long

' 書込プロパティ
Property Let RGB(代入値 As Long)
    RGB_ = 代入値
    R_ = RGB Mod 256
    G_ = Int(RGB / 256) Mod 256
    B_ = Int(RGB / 256 / 256)
    
    Call リンクするオブジェクトを着色する
End Property
Property Let R(代入値 As Long)
    R_ = 代入値
    RGB_ = VBA.RGB(R_, G_, B_)
    Call リンクするオブジェクトを着色する
End Property
Property Let G(代入値 As Long)
    G_ = 代入値
    RGB_ = VBA.RGB(R_, G_, B_)
    Call リンクするオブジェクトを着色する
End Property
Property Let B(代入値 As Long)
    B_ = 代入値
    RGB_ = VBA.RGB(R_, G_, B_)
    Call リンクするオブジェクトを着色する
End Property
Property Set リンクするセル(代入値 As Range)
    Set リンクするセル_ = 代入値
    If is文字色をリンクする Then
        RGB = リンクするセル_.Font.Color
    Else
        RGB = リンクするセル_.Interior.Color
    End If
End Property
Property Set リンクするShape(代入値 As Shape)
    Set リンクするShape_ = 代入値
    If is文字色をリンクする Then
        RGB = リンクするShape_.TextFrame.Characters.Font.Color
    Else
        RGB = リンクするShape_.Fill.ForeColor.RGB
    End If
End Property

' オブジェクトの着色
Sub リンクするオブジェクトを着色する()

    If Not リンクするセル_ Is Nothing Then
        If is文字色をリンクする Then
            リンクするセル_.Font.Color = RGB_
        Else
            リンクするセル_.Interior.Color = RGB_
        End If
    End If
        
    If Not リンクするShape_ Is Nothing Then
        If is文字色をリンクする Then
            リンクするShape_.TextFrame.Characters.Font.Color = RGB_
        Else
            リンクするShape_.Fill.ForeColor.RGB = RGB_
        End If
    End If
    
End Sub

' 読取プロパティ
Property Get RGB() As Long
    RGB = RGB_
End Property
Property Get RGBテキスト() As String
    RGBテキスト = R_ & "," & G_ & "," & B_
End Property
Property Get R() As Long
    R = R_
End Property
Property Get G() As Long
    G = G_
End Property
Property Get B() As Long
    B = B_
End Property
Property Get リンクするセル() As Range
    Set リンクするセル = リンクするセル_
End Property
Property Get リンクするShape() As Shape
    Set リンクするShape = リンクするShape_
End Property

解説

クラスの目的と設計については上記の通りです。

動きの理屈は先ほどの「Rに関連したコード集」を見るとわかりやすいので、
そちらをじっくり見てみてください。


実際に書くときは「RのProperty Get/Letを並べる」以下の書き方↓より、

Property Get R() As Long
    R = R_
End Property
Property Let R(代入値 As Long)
    R_ = 代入値
    RGB_ = VBA.RGB(R_, G_, B_)
    Call リンクするオブジェクトを着色する
End Property

 
各色のProperty Letを3つ並べる」以下の書き方の方↓

Property Let R(代入値 As Long)
    R_ = 代入値
    RGB_ = VBA.RGB(R_, G_, B_)
    Call リンクするオブジェクトを着色する
End Property
Property Let G(代入値 As Long)
    G_ = 代入値
    RGB_ = VBA.RGB(R_, G_, B_)
    Call リンクするオブジェクトを着色する
End Property
Property Let B(代入値 As Long)
    B_ = 代入値
    RGB_ = VBA.RGB(R_, G_, B_)
    Call リンクするオブジェクトを着色する
End Property

こちらの方が、作りやすく読みやすい場合が多いです。


このようなクラスは「Letは複雑だけどGetはただの代入」になりやすいので、
Property Get は下にまとめて追いやっておくことが私は多いですね。


あとは補足になりますが、今回「RGB」というプロパティ名を使ったので、
このままではRGB関数がこのクラス内で使えません。(名前被り)


この問題は以下の通り「親オブジェクト」を明示することで解決できます。

RGB_ = VBA.RGB(R_, G_, B_)

これで「自作のRGB」ではなく「VBAさんのRGB」を呼ぶことができます。

名前被りは基本これで対応ができますので知っておきましょう。

実装例

最後にこのクラスを実装した例を置いておきます。

↓こんな風に「R,G,Bを編集するとリアルタイムで色が変わる」シートを作りました。

色編集シート使用アニメ


この設定コードはイベントプロシージャ「Worksheet_Change」に書きますが、
今回のクラスを使うことで、↓のように記述することができるようになります。

' セルの編集時
Private Sub Worksheet_Change(ByVal Target As Range)
    Application.EnableEvents = False

    If Not Intersect(Target, Range("C3:E3")) Is Nothing Then
        
        With New ClassRGB操作
            Set .リンクするセル = Range("B3")
            .R = Range("C3")
            .G = Range("D3")
            .B = Range("E3")
        End With
    
    End If

    Application.EnableEvents = True
End Sub

非常に簡潔になっていますね。


このように「お互いに連動しあう複数の値」があったときには、
クラス+Propertyプロシージャの活躍の場があるかもしれません。


そんな場面に出くわしたら、練習がてらクラスを作ってみてください。


ちなみに、本クラスはExcelコミュニティ「Excel-Fun.xls*」のイベント
課題チャレンジ共有会002【最も近い色を見つけよう】の回答に使用しました。
課題共有会002【最も近い色を見つけよう】

本課題には20名近い方のご回答が集まっており、
実際のExcelファイルをダウンロードして閲覧することができます。

他の人の作ったマクロを見れる機会はなかなかありませんので、
興味があれば覗いてみてください。


◆ Excel-Fun.xls*(Discord)への参加はこちら
www.limecode.jp

◆ 今回の課題提出スレッドはこちら
VBA課題チャレンジ共有会002【最も近い色を見つけよう】回答スレッド

◆ 私の回答はこちら
VBA課題チャレンジ共有会002【最も近い色を見つけよう】和風スパゲティ回答




以上の内容はhttps://www.limecode.jp/entry/class/rgb-calculatorより取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14