VBAクラス入門:クラスとは?オブジェクト指向とは?
VBAを覚えて、いろいろ作りながらネットで調べたりしていると、クラスとかオブジェクト指向といった言葉に出くわします。
VBEの「挿入」の一番下にある「クラスモ ジュール」は気になっていたかもしれません。
このクラスモジュールを使ってクラスを作ります。
そして作ったクラスがオブジェクトになります。
しかし、そもそもエクセルそのものがオブジェクトの集まりで出来ています。
エクセルのシートもセルもそれらが全てオブジェクトであり、それがクラスであり、オブジェクト指向で作られています。
VBAを理解する上で、クラスの理解やオブジェクト指向の理解は必ず役に立つものです。
オブジェクトとは
まずは何かの物体、つまりは対象物と理解すれば良いでしょう。
ワークシート、セル、グラフ、これらが全てオブジェクトです。
オブジェクト指向とは
対象物を部品を使って組み立てるように表現してプログラミングしていく事になります。
・継承 (inheritance)
・多態性 (polymorphism)
このあたりの用語がでてくると、、、
心配はいりません、少なくともVBAでは、継承も多態性も使えないのですから、
(継承としてはインターフェースだけ使えますが、急ぎ覚える必要はないでしょう。)
従って、カプセル化だけを意識すれば良いのです。
カプセル化
つまり、関連するものを一つのカプセルとしてまとめ、それを使いまわすことになります。
当然、人によって関連の範囲は変わってくることになります。
つまり、人によってクラスの作り方も変わってくるということです。
「自分に関連する人物」というクラスを作るとして、まずデータとしては、
家族、友人、仕事の同僚、学校の同級生、近所の住人・・・
どこまでを想像し、どこまでを一つにまとめるかは、人それぞれ違ってきます。
全部を一つにまとめても良いし、それぞれを別々にまとめても良い。
まとめる範囲が違えば、必要な操作も変わってきます。
どれが適切なのかの正解はないことがほとんどです。
実践の中で、自ら模索し決定していくことになります。
必要な情報のみ外部に公開し、不必要なものは非公開として隠蔽するのです。
つまり、透明なカプセルではなく、不透明なカプセルを作るということです。
そして、カプセルの中に入れたり、カプセルの中から取り出したりする場合は、
専用の出入り口(これがプロパティ)を作ります。
その出入口は、入り口専用・出口専用にすることもできます。
カプセルの中を操作できないようにしておき、カプセルの中を操作したいときは、
カプセルについているボタンを押して操作(これがメソッド)できるようにします。
オブジェクト指向とカプセル化とクラス
といいますか、オブジェクト指向で独自オブジェクトを作るためにクラスが存在しています。
最も意識すべきはカプセル化だと言って良いでしょう。
・必要な情報のみ外部に公開し、不必要なものは非公開として隠蔽。
クラスを使えばカプセル化できるわけではないということです。
一つのキャビネットには関連するものを整理して入れ、扉を閉めておく。
これは人間がやることであり、これをやらなければいみがありません。
キャビネットに適当にものを入れて扉を開けっぱなしでは、単に物の場所を移動しただけです。
そんなことなら、キャビネットは必要ありません。
クラスを使ってカプセル化したオブジェクトを作るということです。
クラスの必要性と利点
「プログラムの強度や凝集度は高まり、結合度は下がる」
これが利点と言われても、まあ大抵の人は「何それ」ってことになるはずです。
(細部まで完全に同じ動作になるかは別として)
RaiseEventで、自作のイベント処理を作るような場合ですと、クラスが良いのですが、
これとて、他の方法で実装できるものがほとんどになるはずです。
※RaiseEventの説明は割愛します、興味のある方は別途調べて下さい。
つまり、余程大規模なシステムを作る以外では、
無くてはならないものではなく、使えれば便利なものだということです。
逆の言い方をすれば、
クラスが使いこなせるようになると、これほど便利なものはなく、
もし一切クラスを使わずに作れと言われると困ってしまうくらいの存在となります。
一般的なクラスに関する説明
オブジェクトの概要
Visual Basicで行うほとんどすべての作業は、オブジェクトにかかわっています
classはある対象の抽象表現であり、オブジェクトはそのクラスを表す実例です。
※ほほ原文のまま
オブジェクトとクラス
クラスは、オブジェクトの変数、プロパティ、プロシージャ、およびイベントを記述します。
オブジェクトはクラスのインスタンスです。
クラスを定義すると、必要な数のオブジェクトを作成できます。
クラスを定義したら、必要な数のオブジェクトを作成することができます。
オブジェクトとそのクラス間の関係を理解するために、クッキーの抜き型とクッキーを考えてみましょう。
クッキーの抜き型はクラスです。
それは、クッキーの特徴 (大きさや形など) を定義します。
クラスを使用して、オブジェクトを作成します。
オブジェクトはクッキーです。
メンバーにアクセスする前に、オブジェクトを作成する必要があります。
※ほほ原文のまま
インスタンスについての補足します
クラスはあくまで型であり実態を持っていません。
クラスで作った実体がインスタンスでり、それがオブジェクトです。
短くまとめると、
クラスは型(オブジェクトの設計図)で、型を使って実体化(インスタンス)したものがオブジェクトです。
つまり
オブジェクトとは、クラスのインスタンスであるという事になります。
あくまでイメージですが、以下のようなとらえ方をしても良いでしょう。
一般名詞は特定のものを指しません、物や概念を指すものです。
固有名詞は、特定のものであり、唯一のものです。
つまり、一般名詞は実体を伴わない概念であり、固有名詞は特定の実体を指しています。
クラスは一般名詞で、オブジェクトは固有名詞
漠然とこんな感覚でとらえても良いでしょう。
クラスの比喩的説明
自動車クラス
色
重量
長さ
幅
ドアの数
排気量
Dim 自動車オブジェクト As New 自動車クラス
自動車オブジェクトのプロパティを設定
自動車オブジェクト.色 = 赤
自動車オブジェクト.重量 = 1.5t
自動車オブジェクト.長さ = 3.8m
自動車オブジェクト.幅 = 1.9m
自動車オブジェクト.ドアの数 = 4
自動車オブジェクト.排気量 = 4,000cc
出来上がった自動車で、いろいろな事をしていくことになります。
クラスの使い方
Dim objFSO As FileSystemObject
Set objFSO = New FileSystemObject
これがクラスです。
これでインスタンスが作成され、つまりオブジェクトとして使えるようになります。
定義しただけでは、Dim objFSO As FileSystemObject、これだけでは、オブジェクトとして使用できません。
インスタンスを生成して、初めてオブジェクトとして使用できるようになります。
これは、型の定義とインスタンスの生成をまとめて行っている事になります。
Dim 変数 As クラス名
Set 変数 = New クラス名
または、
Dim 変数 As New クラス名
同じクラスから、複数のインスタンスが生成できます。
Dim 変数1 As New クラス名
Dim 変数2 As New クラス名
変数1と変数2は、同じクラスからインスタンス生成した、別々のオブジェクトです。
セダンやSUVを作り出すという感じで理解すれば良いでしょう。
クラスを体験してみる
これらを延々と文章で説明しても、かえって混乱するだけのようにも思えます。
「百聞は一見に如かず、百見は一行にしかず」
とにかく「やってみる」という事も時には重要な事だと思います。
第12回.エクセルの言葉を理解する(オブジェクト、プロパティ、メソッド)
クラスを作ると言う事は、オブジェクトを作ると言う事です。
オプションの変更
クラス内のエラー行で停止する設定に変更します。
詳細は、VBEの使い方:ツールのオプション設定を参照してください。
「メニュー」→「ツール」→「オプション」
「全般」タブ→「エラートラップ」
クラス モジュールで中断を選択しておいてください。
全てのモジュールが対象になります。
クラス モジュールの挿入
ショートカットはAlt→I→C
クラス名の変更
プロパティの作成
取得とは、クラスを使う側(オブジェクトを使う標準モジュールのプロシージャ)から見て取得ということです。
変数 = Range("A1").Value
このValueプロパティがGetです。
設定とは、クラスを使う側(オブジェクトを使う標準モジュールのプロシージャ)から見て設定ということです。
Range("A1").Value = 100
このValueプロパティがLetです。
オブジェクトの場合は、Letではなく、Setになります。
GetとLet、または、GetとSetは同一の名前が使えます。
通常は、同一名にして、ペアで作成します。
つまり、値の設定と取得を同じプロパティ名にすることで使いやすくできるという事です。
RangeのValueプロパティには、GetとSetがあるので、設定と取得が同じValueで使えています。
RangeのAddressプロパティは設定できません。
つまりGetのみの読み取り専用プロパティということです。
メソッドの作成
標準プロシージャでの扱いと同様になります。
つまりPublicは、クラス外から使えるメソッドになります。
Privateで定義されたメソッドは、クラス外から直接使う事はできません。
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を使います。
設定するプロパティとして、Property Let
取得するプロパティとして、Property Get
シート名は単なる値なので、Property Letを使います。
Property Getだけなので、読み取り専用プロパティとなっています。
Property Getだけなので、読み取り専用プロパティとなっています。
戻り値が必要ないので、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クラス入門:クラスとは?オブジェクト指向とは?
クラスを使った全ブック(他ブック)のイベント補足
VBAクラスの作り方:列名の入力支援と列移動対応
VBAクラスの作り方:列名のプロパティを自動作成する
VBAクラスの作り方:独自Rangeっぽいものを作ってみた
クラスとイベントとマルチプロセス並列処理
クラスとCallByNameとポリモーフィズム(多態性)
オートフィルターを退避回復するVBAクラス
オートフィルター退避回復クラスを複数シート対応させるVBAクラス
コレクション(Collection)の並べ替え(Sort)に対応するクラス
VBAクラスのAttributeについて(既定メンバーとFor Each)
新着記事NEW ・・・新着記事一覧を見る
TRIMRANGE関数(セル範囲をトリム:端の空白セルを除外)|エクセル入門(2024-08-30)
正規表現関数(REGEXTEST,REGEXREPLACE,REGEXEXTRACT)|エクセル入門(2024-07-02)
エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.セルのクリア(Clear,ClearContents)|VBA入門
8.メッセージボックス(MsgBox関数)|VBA入門
9.条件分岐(Select Case)|VBA入門
10.マクロとは?VBAとは?VBAでできること|VBA入門
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。