今回はクラスモジュールづくりのサンプルとして、
「色の操作を補助するクラス」を作ってみました。
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【最も近い色を見つけよう】の回答に使用しました。

本課題には20名近い方のご回答が集まっており、
実際のExcelファイルをダウンロードして閲覧することができます。
他の人の作ったマクロを見れる機会はなかなかありませんので、
興味があれば覗いてみてください。
◆ Excel-Fun.xls*(Discord)への参加はこちら
www.limecode.jp
◆ 今回の課題提出スレッドはこちら
VBA課題チャレンジ共有会002【最も近い色を見つけよう】回答スレッド
◆ 私の回答はこちら
VBA課題チャレンジ共有会002【最も近い色を見つけよう】和風スパゲティ回答