クラス(モジュール)とは何かを3つのポイントをもとに検証
「クラスモジュールとは何か?」ExcelVBAのユーザー様からいただく質問の中でこの質問が1番多いです。
クラスを一言で表現すると「オブジェクト、プロパティ、メソッドの設計図」です。
つまり「配下のプロパティ、メソッドの仕様を含め自分の考えでオブジェクトの仕様を設計する」という事です。
これでは分かりにくいかもしれないので具体的に考えてみましょう。既存のクラスを見る事にします。
画像はオブジェクトブラウザーです。(VBEでF2キー押下)よく使うRangeクラスに赤枠を付けました。
これがクラスです。このクラスから生成されるのがオブジェクトです。
Rangeクラス(オブジェクト)の右側にはRangeクラスに用意されたプロパティやメソッド(メンバー)が並んでいます。
クラスを勉強するとこのような要素を自作する事ができます。もちろん作るだけではなく使用も可能です。
便利な機能である反面でクラスの概念を理解するのは非常に難しいです。よって勉強を回避しても良いです。
理由は「使い時が限りなく少ない」からです。初心者の場合ExcelVBAにおけるクラスは費用対効果が低いです。
新規のクラスを使わなくても既存のクラス群で大抵の事はできてしまいます。
最初の頃はクラスを覚えなくても仕事に支障が出る事はまず無いです。
クラスは難しいと言われると余計気になりますよね。そんな方のために分かりやすくクラスを説明してみます。
この記事の目的は「クラスの理解」です。3つのポイントをもとにクラスとは何かを考えていきましょう。
- クラスとは何か(何をどこまで知る必要があるのか)
- クラスの使い時(使いどころ)
- クラスが理解できないと困るのか
次の記事では1つの作業に対して「クラスを使ったコード」と「クラスを使わないコード」を用意しました。
比較する事でクラスを理解します。今回の記事を読み進めてもらえるとよりクラスが分かる様になります。
関連記事
「クラスを使ったコード」と「クラスを使わないコード」を用意しました。どちらも同じ仕事ができます。
両方のコードを比較する事でクラスの理解につながります。
クラスを使う【サンプルコード】VBAでクラスを使ったコードと使わないコードを比較する
初心者からクラスを含めマクロを勉強する際何から勉強すると効率が良いのかが分かるロードマップです。
学習順序を決めましたマクロは何から勉強するのか|学習をサポートするためのロードマップを作成
関連書籍
私この本を何年も読み続けてやっと読める様になりました。クラスについてもしっかり記述があります。
VBA関連の本の中ではトップクラスに難しいのですが内容が分かる様になるととても読みやすい本です。
電子書籍(Kindleストア)はこちらです。私一部の書籍は電子書籍で購入しています。
電子書籍をVBEと同じ画面で横に並べながら作業する事で作業効率が劇的にあがります。
1_クラスとは
Wikipediaのクラスに対する説明を引用します。クラスはオブジェクトを生成する為の設計図です。
オブジェクト指向プログラミングにおけるクラス(英: class)は、オブジェクトを生成するための設計図あるいはひな形に相当するものである。
抽象データ型の一つ。クラスから生成したオブジェクトの実体のことをインスタンスという。
Wikipedia:クラス(コンピュータ)より抜粋
「インスタンス」という聞き慣れないキーワードが出てきました。インスタンスについて考えてみましょう。
ここから少し難しくなりますが途中で画像を使って情報を整理しますので心配せずに読み進めてください。
インスタンスは「クラスを実体化した際生成されたオブジェクト」
インスタンスとはクラスを実体化した際生成されたオブジェクトです。・・・と言われても分かりにくいですよね。
この情報だけではイメージしにくいので少し思考の角度を変えてみます。実際に会話する時の使い方を見てみましょう。
2つの文章からクラス単体ではなく周辺にも色々なキーワードが存在していることが分かりますね。
ここではクラスを理解するには「関連キーワードと一緒に勉強しないといけない」という事を認識してください。
- クラスをインスタンス化するとインスタンスが生成される
- ○○クラスという設計図を実体化するとオブジェクトが生成される
話をインスタンスに戻します。インスタンスはコード内で使うオブジェクトの事を指しています。
設計図のままでは使えないクラスをコードとして使える様に変換した時に生成されるオブジェクトがインスタンスです。
初心者の頃は「インスタンス=オブジェクト」と読み替えて覚えてください。
他にも新しい言葉が出てきました。インスタンスに似ている「インスタンス化」です。このあと説明していきます。
インスタンス化は「オブジェクトの実体化」
インスタンス化とは「オブジェクトの実体化」です。「オブジェクトの生成」とも言われます。
初心者の頃は「インスタンス化=オブジェクトの実体化」と読み替えてください。
クラスを実体化させる(画像でイメージを共有する)
そろそろ頭が疲れてきましたよね。新しい用語が続いてますので一旦情報を整理しましょう。
紹介した用語をもとに画像を使って情報を整理してみました。クラスとインスタンスの関係をイメージできます。
用語の整理とともにポイントを1つ紹介しておきます。
クラスは「クラスだけ用意しても構想だけ(設計図止まり)で何も起きない」という事をご理解ください。
この画像をもとに先程見ていただいたキーワードを読むとより理解が進みます。
クラスを含めた一連の作業、考え方をイメージしてください。まだイメージの段階で大丈夫です。
- クラスをインスタンス化するとインスタンスが生成される
- ○○クラスという設計図を実体化するとオブジェクトが生成される
以降で実際にクラスを作ってみる事でより理解が進みます。次に進みましょう。
クラスを用意するだけでは何も起きない
クラスを使用する為にはメモリ内に実体化させる必要があります。実体化後にはオブジェクトとして使用する事になります。
この様にクラスは「設計図」であるクラスを「実体化」しオブジェクトを生成する所までセットで勉強が必要です。
ではこの流れで実体化以降の流れを見ていきましょう。
実体化となると現物が用意されるようなイメージですが実際はPCの中での話なので現物が用意される事は無いです。
イメージとしては「クラスをメモリの中に定義してあげる」事を実体化と呼んでいます。
この後どうやってクラスを実体化してオブジェクトとして使うのかを実践していきます。
実際にクラスを用意してみる
続いて「設計図」と「実体化」という2つのキーワードをもとにクラスを準備していきましょう。
「設計図」と「実体化」が理解できるとクラスを自作できる&クラスを使う事ができる様になります。
クラスの設計図(構造)
設計図というのは例えなので実際は少し違う事をするのですが大差無いです。やる事はこの2つです。
- クラス自体をVBEに用意する ・・・ のちにオブジェクトとなるモジュールを用意
- 用意したクラスモジュールにコードを書く ・・・ プロパティ、メソッドを用意
1つずつ見ていきます。
1_クラス自体をVBEに用意する
実体化(インスタンス化)した後にオブジェクトとなるクラス自体をVBEに用意していきます。
新規のExcel「新規 Microsoft Excel ワークシート.xlsx」を1つ用意してVBEを開いてください。
クラスモジュールを用意する方法は標準モジュールと同じです。(分からない方はこちらの動画をご覧ください)
プロジェクトエクスプローラーに「クラスモジュール」が表示され「Class1」というクラスが用意されます。
クラスの名前を変える際はプロパティウインドウの(オブジェクト名)を書き換えてください。
「Class1」を「Price」に書き換えてみました。
2_用意したクラスモジュールにコードを書く
用意されたクラスモジュールもコードウインドウを持っています。
ここに書いたコードはクラスがインスタンス化された際にプロパティ、メソッドとして実体化されます。
少しだけコードを書いてみました。
書いたとは言えないぐらいの量ですがこれでプロパティとメソッドを用意する事ができます。
Option Explicit
Public a As Long '変数を定義(宣言)しただけ
Sub test()
'中身は何も無しのSubプロシージャ
End Sub
ここでオブジェクトブラウザーを見ます。上部のプルダウンでVBAProjectを選択しクラスを確認します。
先程用意した「Price」クラスを選択するとプロパティ「a」とメソッド「test」が用意されたことが分かります。
これでオブジェクト、プロパティ、メソッドの設計図を用意する事ができました。
参考:実際の運用ではもう少し複雑なコードになります
スコープの話をします。今回用意した変数「a」はPublicで設定していますがPrivateで設定する事もできます。
運用時は「Property Let」、「Property Get」、「Property Set」プロシージャを使い値を取り回します。
実体化(インスタンス化)
クラスの設計図を用意する事が出来ましたのでクラスを使用できる様に実体化します。ここもやる事は2つです。
- 標準モジュールを用意する
- 実体化のコードを書く
1_標準モジュールを用意する
普段標準モジュールを用意する方法で用意してください。(動画はこちら)
2_実体化のコードを書く
標準モジュールの中に1つプロシージャを用意します。ここでは以下の様にコードを書いてください。
Sub メインプロシージャ()
Dim myP As Price
Set myP = New Price
myP.a = 1
myP.test
End Sub
「myP」というのはクラス「Price」をセットする変数名です。よってどんな名前でも良いです。
クラスごと変数「myP」にセットしてしまうという考え方です。これで実体化(インスタンス化)完了です。
コードを実行してみます。実体化が終わるとローカルウインドウに変数myPが表示されます。
画面右下の型を見てください。変数myPは「Price」ですと表示されています。
myP.a = 1 というコードでPriceクラスを格納した変数myPのプロパティ「a」に1が代入(入力)されています。
このあとtestメソッドが実行されますが中身は無いので何も起きません。
こうやって標準モジュールから作成したクラスを呼び出して使う事になります。
これで一通り作業が終わりました。クラスの「設計図」を用意して「実体化」してみました。
データを閉じる際は拡張子「.xlsm」で保存してください。(拡張子についての詳しい説明はこちら)
続いてクラスの特徴やメリットを解説していきます。
特徴
クラスには3つの特徴があります。しかしVBAでは「カプセル化」しか使えません。
よってカプセル化だけ再度Wikipediaから引用します。他の2つに興味がある方は各自で調べてみてください。
- カプセル化
- 継承
- ポリモーフィズム
関連する変数や操作などをクラスの所属物として一つにまとめてしまうことを、クラスによる情報のカプセル化(encapsulation)と呼ぶ。適切なカプセル化により、データ構造やアルゴリズムなどを変更したとしても、変更箇所はカプセル化されたクラス領域内だけで済み、変更箇所がクラス外の関連ソースコード全体にまで散乱・波及してしまうことを防ぐことができる。
Wikipedia:クラス(コンピュータ)より抜粋
実は先程用意した「Price」クラスでは「カプセル化」が実装されていました。
用意したコードは「Price」クラスの中でプロパティ「a」とメソッド「test」という2つの要素を持っていましたね。
プロパティ「a」とメソッド「test」は現状では連携を持たせてないので干渉する事はありません。
しかし後から関連を持たせるつもりで1つのモジュールに格納して一緒に管理しているという状態です。
また各要素に変更を加える際も要素自体が分割されている事により変更範囲を最小限に留める事ができます。
クラスを起点としたこれらの仕様のことを「カプセル化」と呼びます。
カプセル化の中に隠蔽という機能もありますがここでは説明しません。次の記事で取り上げる予定です。
一息つきましょう:クラスを作った時に抱いた「疑問」
私はVBA初心者の頃に自身で初めてクラスモジュールを用意した際このような感情を持ちました。
「だから何なのか?」という感情です。クラスを作ったところで何になるんだろうと考えてしまいました。
結論としてはクラスは自分でオブジェクト、プロパティ、メソッドが作成できるという非常に優れた機能(要素)です。
ただしほとんどの仕事は既存のクラス群で対応できてしまうのでクラスを使うことはあまり無いのが現状です。
今思えば「だから何なのか?」という感情はクラスを自分の仕事に盛り込むことが出来なかったからだと思っています。
メリットも見出せず便利さも感じられませんでした。今なら分かるのですがこれは初心者のうちは仕方のないことです。
よって初めてクラスを勉強される方は「こんな機能もあるんだな」ぐらいで勉強を進めていただくことをおすすめします。
必ず理解してすぐ仕事で使おうと考えていると自分を追い込んでしまうことになりますのでご注意ください。
続いてクラスの「使い時」や「メリット/デメリット」をご覧ください。
クラスを理解するのは中級者から上級者になってからで良いという事が分かってきます。
2_使い時(使いどころ)
クラスがどんなものなのか少しだけ分かったとしましょう。次は「使い時」です。いつ使うのでしょうか?
使い時は限りなく少ない
頑張って出してこの3つです。メリットも感じないので使い時もそんなに無いです。
よってそれぞれを深く説明はしません。
- クラスを使ったマクロのメンテナンスを依頼された時(レアケース)
- オブジェクト、プロパティ、メソッドについて勉強したい時(要素を自作したいと思った時)
- 大規模な開発をする時(今はVBAで大規模開発はしないのでこれは無いかもしれない)
クラスを使わなくても既存のクラス群で十分コードを書く事ができます。
この事からも分かる様にほとんどの事例においてはクラスを使う必要がないです。
あえてクラスを使う事もある
1人で使うようなコードだったりVBEでパスワードをかけて他者に渡すようなコードの時はクラスを使います。
「コードが難しくなってもグループのメンバーや他者に説明する必要が無い」という理由からです。
クラスを使う事でプロシージャ(プログラム)が複数、複雑になるのでサブルーチンの理解が必要です。
複雑にはなりますがVBA中級者以上の方はサブルーチンでプロシージャを分けると効率が良くなる事があります。
よってクラスを使うケースもあります。しかし初心者からするとコードが読めなくなるのでデメリットになります。
この事から1人で使う時やVBEにパスワードをかける時には自身の効率だけを考えてクラスを使う事があります。
クラスを使う事によるメリット、デメリット
それぞれのポイントを解説します。
クラスを使うメリット
皆様が気になる「クラスを使う事によるメリット」です。勉強する為の目的としてメリットが知りたい方も多い事でしょう。
これはあくまで私の意見ですので記事を読んでいる皆様が勉強したうえで判断してください。
VBAのクラスに関しては使用、運用面で便利さやメリットをあまり感じた事があまりないので「無い」です。
理由はクラスを使わなくても既存のクラス群で同じような仕事ができるからです。
ただし思考面(コードを用意する際の考え方)ではメリットを感じることがあります。記事後半で説明します。
クラスを使うデメリット
会社などグループで使うようなマクロにクラスを用いたコードを用意すると高確率で引継ぎができません。
理由は「単純に理解できないから」です。初心者ばかりの低スキルのグループの時はクラスを使わない方が良いです。
3_クラスが理解できないと困るのか
結論としては「ほとんど困る事はない」です。理由はクラスを使ったコードの数が絶対的に少ないからです。
当たり前ですが「クラスを使ったマクロの仕事をする時」には困ります。しかし非常にレアなケースです。
クラスを理解できてないうちにクラスを使ったマクロに出会ったら仕方がないと思い諦めましょう。
参考ですがクラスが理解できる事によるメリットと理解できない事によるデメリットを提示しておきます。
クラスが理解できる事によるメリット
クラスを勉強して理解できると以下のようなメリットがあります。
- クラスを使ったマクロの仕事を受ける事ができる
- オブジェクト、プロパティ、メソッドの使い方に対する理解が深まりコードを理屈で考えられる
- コードを見られても解読されたりコードを書き換えられる機会が格段に減る
2番のようにコードを書く際の「考え方」については大きなメリットがあると感じています。
オブジェクト、プロパティ、メソッドを自作する事で既存のクラスの構造を想像できる様になります。
そうなるとVBAProject単位でどのモジュールにどこまでのコードを書くと効率が良いのか分かってきます。
コードを書く際の環境まで考えられるようになるのがクラスが理解出来た時に得られるメリットです。
参考:OfficeScriptでクラスを使う事ができる
Web版のExcelではマクロが使えません。VBEからワークシート上に指示をすることができなくなります。
マクロの様なものを用意するにはOfficeScript(Officeスクリプト)でのコーディングが必要になります。
OfficeScriptはJavaScriptのスーパーセット(上位互換)であるTypeScriptという言語がベースになっています。
数年後のExcelではJavaScriptがベースのOfficescriptを使いWeb上のワークシートの情報を操作する事になります。
このOfficeScriptではクラスを使うメリットがあります。VBAのクラスより使える機能もたくさんあります。
詳細は省略しますがしっかりとしたクラスを使う事によるメリットがあるのでクラスを使う事になります。
VBAのクラスが理解出来ているとOfficeScriptを使う際にクラスの勉強が非常に楽になります。
画像はWeb版のExcelでクラスを使っている様子です。(画像をクリックすると拡大します)
クラスはVBAやOfficeScriptに限らす他のプログラミング言語でも用意されている概念、機能です。
VBAの中で勉強しておけば他の言語を学習した際に学習コストが下がります。
クラスが理解できない事によるデメリット
3種類出してみましたがまとめると「コードの質が上がらない」というところに落ち着きます。
- クラスを使ったマクロの仕事を受ける事ができない
- コードを勉強する際暗記したりコピペで何とかしようと考えてしまう(理屈ではなく形で覚える)
- コードを見られた際に読み取られたり書き換えられる可能性が高くなる
質なんて上がらなくても仕事が片付けば良いでしょ?という意見もあります。私もそう思っています。
動けば問題無いという思考の人はデメリット無しです。特に勉強する必要は無いです。
参考:マクロを勉強するのではなく仕事を片付けるのが優先な方へ
こちらの書籍はこの考え方にピッタリです。マクロは関数などと同じで全部を覚えようとしないことが重要です。
定時に帰りませんか?マクロの教科書として使える|学習範囲を限定して勉強4時間の仕事を20秒に減らす
その他
クラスを勉強するより配列やライブラリ(FileSystemObject等)にある要素を勉強をした方ができる事が増えます。
加えて「クラスを知っている」なんて言うとずっと説明させられるので「分からない」と言っておいた方が楽です。
FileSystemObjectを使用したコードVBAで画像を取り込む高速で画像自体を取得しエクセルに貼り付ける
まとめ
クラスとは何かについて解説しました。「本当に難しいのか」については正直なところ「難しい」です。
よって私の結論としては「難しいですができるなら勉強した方が良い」という事になります。
普通にVBAを使うだけならクラスの使い時やメリットを感じることが少ないので優先順位は落ちますね。
VBAが理解出来てくると次第にオブジェクト関連の理解が進みます。クラスの勉強はその時でも十分です。
それでも気になる方は次の記事を読んでください。
1つの作業をする中でクラスを使ったコードと使わないコードを用意してみました。比較すると理解が進むかもしれません。