ExcelマクロVBA技術解説
VBAのクラスとは(Class,Property,Get,Let,Set)

ExcelマクロVBAの問題点と解決策、エクセルVBAの技術的解説
最終更新日:2019-02-19

VBAのクラスとは(Class,Property,Get,Let,Set)

VBAを覚えて、いろいろ作りながらネットで調べたりしていると、
クラスやらオブジェクト指向やらという言葉に出くわします。
いくら言葉を尽くしても、これらクラスやオブジェクト指向を完全に説明しつくすことは難しいと思われます。



オブジェクトとは
操作対象の事ですと説明されたりしますが、
まずは何かの物体、つまりは対象物と理解すれば良いでしょう。


オブジェクト指向とは

オブジェクト同士の相互の作用として、システムの動作をとらえる考え方であり、
対象物を部品を使って組み立てるように表現してプログラミングしていく事になります。

オブジェクト指向における三大要素
・カプセル化 (encapsulation)
・継承 (inheritance)
・多態性 (polymorphism)

このあたりの用語がでてくると、、、
心配はいりません、少なくともVBAでは、継承も多態性も使えないのですから、
(継承としてはインターフェースだけ使えますが、急ぎ覚える必要はないでしょう。)
従って、カプセル化だけを意識すれば良いのです。


カプセル化

関連するデータやその操作を一つ(カプセル)にまとめることを言います。
つまり、関連するものを一つのカプセルとしてまとめ、それを使いまわすことになります。

これは概念的なものになりますので、くどくど言葉で説明してもなかなかピンとこないかもしれません。

一番わかりづらいのは、「関連する」というのが抽象的過ぎるということだと思います。
当然、人によって関連の範囲は変わってくることになります。
つまり、人によってクラスの作り方も変わってくるということです。
「自分に関連する人物」というクラスを作るとして、まずデータとしては、
家族、友人、仕事の同僚、学校の同級生、近所の住人・・・
どこまでを想像し、どこまでを一つにまとめるかは、人それぞれ違ってきます。
全部を一つにまとめても良いし、それぞれを別々にまとめても良い。
まとめる範囲が違えば、必要な操作も変わってきます。
どれが適切なのかの正解はないことがほとんどです。
実践の中で、自ら模索し決定していくことになります。

また、カプセル化の重要な要素として、「隠蔽」があります。
必要な情報のみ外部に公開し、不必要なものは非公開として隠蔽するのです。
つまり、透明なカプセルではなく、不透明なカプセルを作るということです。
そして、カプセルの中に入れたり、カプセルの中から取り出したりする場合は、
専用の出入り口(これがプロパティ)を作ります。
その出入口は、入り口専用・出口専用にすることもできます。
カプセルの中を操作できないようにしておき、カプセルの中を操作したいときは、
カプセルについているボタンを押して操作(これがメソッド)できるようにします。


オブジェクト指向とカプセル化とクラス

オブジェクト指向のプログラムを作るにはクラスが必要です。
といいますか、オブジェクト指向で独自オブジェクトを作るためにクラスが存在しています。

少なくともVBAにおいてクラスを使うときに、
最も意識すべきはカプセル化だと言って良いでしょう。

・関連するデータやその操作を一つにまとめる。
・必要な情報のみ外部に公開し、不必要なものは非公開として隠蔽。


一番勘違いしてほしくないのは、
クラスを使えばカプセル化できるわけではないということです。
キャビネットを買ったからと言って事務所が整理されるわけではありません。
一つのキャビネットには関連するものを整理して入れ、扉を閉めておく。
これは人間がやることであり、これをやらなければいみがありません。
キャビネットに適当にものを入れて扉を開けっぱなしでは、単に物の場所を移動しただけです。
そんなことなら、キャビネットは必要ありません。

クラスを使ってカプセル化したオブジェクトを作るということです。


クラスの必要性と利点

クラスを使って、オブジェクト指向を目指すと、
「プログラムの強度や凝集度は高まり、結合度は下がる」
これが利点と言われても、まあ大抵の人は「何それ」ってことになるはずです。

そもそもクラスを使用しないと実現できない処理はありません。

結果としての全体動作だけなら、別の手段で実現可能です。
(細部まで完全に同じ動作になるかは別として)


クラスが必要になる処理としては、
RaiseEventで、自作のイベント処理を作るような場合ですと、クラスが良いのですが、
これとて、他の方法で実装できるものがほとんどになるはずです。
※RaiseEventの説明は割愛します、興味のある方は別途調べて下さい。

つまり、余程大規模なシステムを作る以外では、
無くてはならないものではなく、使えれば便利なものだということです。
逆の言い方をすれば、
クラスが使いこなせるようになると、これほど便利なものはなく、
もし一切クラスを使わずに作れと言われると困ってしまうくらいの存在となります。


いろいろと説明してきましたが、
これらを延々と文章で説明しても、かえって混乱するだけのようにも思えます。
「百聞は一見に如かず」
とにかく「やってみる」という事も時には重要な事だと思います。


ただし、最低限の知識として、
第12回.エクセルの言葉を理解する(オブジェクト、プロパティ、メソッド)
ExcelマクロVBAを書いて実行すると、何やら難しい日本語らしきメッセージが表示されることがあります、エクセルが何かを伝えようとしている訳ですが、何を言っているのかを理解してあげなければエクセルがかわいそうです。しかし、エクセルが表示するエラーメッセージの言葉の意味位は知っていて損はありません。
このページくらいは理解していることとして説明をしていきます。

以下はMSDNより・・・MSDN(Microsoft Developer Network)はMicrosoft社のソフトウェア開発者向けサポートサービス
オブジェクトの概要
オブジェクトは、データおよびそのデータを操作するメソッドを含む構造体のことです。
Visual Basicで行うほとんどすべての作業は、オブジェクトにかかわっています
classはある対象の抽象表現であり、オブジェクトはそのクラスを表す実例です。

オブジェクトとクラス
Visual Basic の各オブジェクトは、クラスによって定義されます。
クラスによって、オブジェクトの変数、プロパティ、プロシージャ、およびイベントが説明されます。
オブジェクトは、クラスのインスタンスです。クラスを定義すると、必要なだけオブジェクトを作成できます。
オブジェクトとクラスの関係は、クッキーとクッキーの抜き型にたとえることができます。
クッキーの抜き型はクラスです。抜き型は、大きさや形など、それぞれのクッキーの特徴を定義します。
このクラスを基にオブジェクトを作成します。このオブジェクトに相当するのがクッキーです。



少し簡単に言うとと、
クラスは型(オブジェクトの設計図)で、型を使って実体化(インスタンス)したものがオブジェクトです。
つまり
オブジェクトとは、クラスのインスタンスであるという事になります。
これがなかなか実感として理解しづらいかもしれません。
あくまでイメージですが、以下のようなとらえ方をしても良いでしょう。

一般名詞と固有名詞、こんな違いとして認識しても良いかもしれません。
一般名詞は特定のものを指しません、物や概念を指すものです。
固有名詞は、特定のものであり、唯一のものです。
つまり、一般名詞は実体を伴わない概念であり、固有名詞は特定の実体を指しています。
クラスは一般名詞で、オブジェクトは固有名詞
漠然とこんな感覚でとらえても良いでしょう。



以下では、自動車というクラスを作る場合の例えになります。

自動車クラス
プロロパティ
名前

重量
長さ

ドアの数
排気量

このように、プロパティはオブジェクトの性質を表すデータになります。

Dim 自動車オブジェト As New 自動車クラス
自動車オブジェクトを作るには、自動車クラスのインスタンスを生成することで作成します。

自動車オブジェトのプロパティを設定
自動車オブジェ.名前 = フェラーリ
自動車オブジェ.色 = 赤
自動車オブジェ.重量 = 1.5t
自動車オブジェ.長さ = 3.8m
自動車オブジェ.幅 = 1.9m
自動車オブジェ.ドアの数 = 4
自動車オブジェ.排気量 = 4,000cc

これで上で設定したような仕様の自動車が出来上がるという事です。
出来上がった自動車で、いろいろな事をしていくことになります。



具体的には
「61.FileSystemObjectの使い方」で出てきた
Dim objFSO As FileSystemObject
Set objFSO = New FileSystemObject

FileSystemObject
これがクラスです。

New FileSystemObject
これでインスタンスを生成します。

そして、objFSOがオブジェクトとして使用可能となります。
定義しただけでは、Dim objFSO As FileSystemObject、これだけでは、オブジェクトとして使用できません。
インスタンスを生成して、初めてオブジェクトとして使用できるようになります。

Dim objFSO As New FileSystemObject
これは、型の定義とインスタンスの生成をまとめて行っている事になります。

一般的な書き方をすると
Dim 変数 As クラス名
Set 変数 = New クラス名
または、
Dim 変数 As New クラス名



同じクラスのオブジェクトは、いくつでも作る事が出来ます
同じクラスから、複数のインスタンスが生成できます。
Dim 変数1 As New クラス名
Dim 変数2 As New クラス名
変数1と変数2は、同じクラスからインスタンス生成した、別々のオブジェクトです。

自動車というクラスをもとに、
セダンやSUVを作り出すという感じで理解すれば良いでしょう。




では、いよいよ実際にクラスを作っていきましょう。
クラスを作ると言う事は、オブジェクトを作ると言う事です。

クラスの挿入
メニューの「挿入」→「クラス」、ショートカットはAlt+I+C
プロジェクトウインドウで右クリックからも挿入できます。

VBA クラス 挿入


クラス名の変更

プロパティウインドウのオブジェクト名で変更します。

VBA クラス オブジェクト名


プロパティの作成

Property Get
プロパティの値を取得するプロシージャです。
取得とは、クラスを使う側(オブジェクトを使う標準モジールのプロシージャー)から見て取得ということです。
変数 = Range("A1").Value
このValueプロパティがGetです。

Property Let
プロパティの値を設定するプロシージャです。
設定とは、クラスを使う側(オブジェクトを使う標準モジールのプロシージャー)から見て設定ということです。
Range("A1").Value = 100
このValueプロパティがLetです。

Property Set
プロパティのオブジェクトを設定するプロシージャです。
オブジェクトの場合は、Letではなく、Setになります。

GetとLet、または、GetとSetは同一の名前が使えます。
通常は、同一名にして、ペアで作成します。
つまり、値の設定と取得を同じプロパティ名にすることで使いやすくできるという事です。
RangeのValueプロパティには、GetとSetがあるので、設定と取得が同じValueで使えています。

読み取り専用プロパティとは、Getプロパティのみのプロパティになります。
RangeのAddressプロパティは設定できません。
つまりGetのみの読み取り専用プロパティということです。


メソッドの作成

Subステートメント、Functionステートメントで作成します。
標準プロシージャーでの扱いと同様になります。

クラス内にPublicで定義されたSubまたはFunctionは、
そのクラスのインスタンスから使用することが出来ます。
メソッドは、そのオブジェクトに何らかの動作をさせるものです。

Rangeであれば、
Delete
Insert
AutoFilter
これらのように、さのオブジェクトに何らかの振る舞いをさせるものになります。



使用例

以下は、独自のワークシートを作るクラスです。
クラスを挿入し、貼り付けて下さい。

Private pSheet As Worksheet

'扱うシートを設定
Public Property Set MySheet(argSheet As Worksheet)
  Set pSheet = argSheet
End Property
'扱うシートを取得
Public Property Get MySheet() As Worksheet
  Set MySheet = pSheet
End Property

'シート名を変更
Public Property Let Name(ByVal argName As String)
  MySheet.Name = argName
End Property
'シート名を取得
Public Property Get Name() As String
  Name = MySheet.Name
End Property

'セル範囲を(開始セル,行数,列数)で指定できるようにする
Public Property Get MyRange(sRange As Range, ByVal RowSize As Long, ByVal ColumnSize As Long) As Range
  Set MyRange = sRange.Resize(RowSize, ColumnSize)
End Property

'セルを(行位置,列位置)で指定できるようにする
Public Property Get MyCells(ByVal RowIndex As Long, ByVal ColumnIndex As Long) As Range
  Set MyCells = MySheet.Cells(RowIndex, ColumnIndex)
End Property

'指定セルのアクティブセル領域に罫線を引く
Public Sub CurrentBorders(sRange As Range)
  sRange.CurrentRegion.Borders.LineStyle = xlContinuous
End Sub

MySheet
扱うシートを設定・取得できるようにしているプロパティです。
設定するプロパティとして、Property Set
取得するプロパティとして、Property Get
シートはオブジェクトなので、Property Setを使います。

Name
シート名を変更・取得できるようにしているプロパティです。
設定するプロパティとして、Property Let
取得するプロパティとして、Property Get
シート名は単なる値なので、Property Letを使います。

MyRange
セル範囲を(開始セル,行数,列数)で指定できるようにするプロパティです。
Property Getだけなので、読み取り専用プロパティとなっています。

MyCells
セルを(行位置,列位置)で指定できるようにするプロパティです。
Property Getだけなので、読み取り専用プロパティとなっています。

CurrentBorders
指定セルのアクティブセル領域に罫線を引くメソッドです。
戻り値が必要ないので、Subプロシージャーで作成しています。

標準プロシージャーで上のクラスを使う場合です。

Dim myClass As New Class1
Set myClass.MySheet = ActiveSheet
With myClass
  .Name = "クラスTEST"
  .MyCells(2, 1) = 1
  .MyRange(.MyCells(3, 1), 1, 3) = 10
  .CurrentBorders sRange:=.MyCells(2, 1)
End With


最初は遊びがてら、上記のコードをいじってみるところから初めてみると良いと思います。
いきなり書籍やWEBで、しっかりクラスを理解しようとしてもかなりの苦労が待ち受けているだけだと思います。
標準モジュールでも簡単に実現できるような簡単なコードから使い始めれば良いでしょう。


ただし既に書いている通り、クラスは無くてはならないものではありませんので、
VBAの基本及び応用において、一通り習得できた後にチャレンジしてみるくらいで十分です。



同じテーマ「マクロVBA技術解説」の記事

VBAのクラスとは(Class,Property,Get,Let,Set)
クラスを使って他ブックのイベントを補足する
VBAクラスの作り方:列名の入力支援と列移動対応
VBAクラスの作り方:列名のプロパティを自動作成する
VBAクラスの作り方:独自Rangeっぽいものを作ってみた
クラスとイベントとマルチプロセス並列処理
クラスとCallByNameとポリモーフィズム(多態性)
オートフィルタを退避回復するVBAクラス
オートフィルタ退避回復クラスを複数シート対応させるVBAクラス
コレクション(Collection)の並べ替え(Sort)に対応するクラス


新着記事NEW ・・・新着記事一覧を見る

VBAのマルチステートメント(複数のステートメントを同じ行に)|VBA技術解説(10月14日)
VBAコードの全プロシージャー・プロパィ一覧を取得|VBAサンプル集(10月12日)
VBAでエラー行位置(行番号)を取得できるErl関数|VBA技術解説(10月11日)
手動計算時の注意点と再計算方法|ExcelマクロVBA技術解説(10月9日)
引数の数を可変にできるパラメーター配列(ParamArray)|VBA入門(10月7日)
VBEの使い方:デバッグ|ExcelマクロVBA入門(10月6日)
VBAにおける配列やコレクションの起点について|VBA技術解説(10月5日)
VBEの使い方:オブジェクト ブラウザー|VBA入門(10月5日)
VBEの使い方:ウォッチ ウィンドウ|VBA入門(10月4日)
VBEの使い方:ローカル ウィンドウ|VBA入門(10月3日)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.RangeとCellsの使い方|ExcelマクロVBA入門
4.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
5.変数とデータ型(Dim)|ExcelマクロVBA入門
6.繰り返し処理(For Next)|ExcelマクロVBA入門
7.マクロって何?VBAって何?|ExcelマクロVBA入門
8.ひらがな⇔カタカナの変換|エクセル基本操作
9.空白セルを正しく判定する方法(IsEmpty,IsError,HasFormula)|VBA技術解説
10.セルに文字を入れるとは(Range,Value)|VBA入門



  • >
  • >
  • >
  • VBAのクラスとは(Class,Property,Get,Let,Set)

  • このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


    記述には細心の注意をしたつもりですが、
    間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
    なお、掲載のVBAコードは自己責任で使ってください。万一データ破損等の損害が発生しても責任は負いません。




    このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
    本文下部へ