VBAによるプログラミングにオブジェクト指向を取り入れます。クラスモジュールは日本語での情報がネットでも本でも少なく、あっても超ムズかしかったので、誰でも分かる様に簡単に解説します。
そもそもクラス名やメソッド名などがアルファベットなのでわかりにくいと思ったので、全部日本語にします。それではLet's Start.
この記事は初段です。
レベルについてはExcel VBAの実力(レベル)を定義してみる 初心者~三段をご参照ください。
目次
そもそもクラスとオブジェクトとは何か
クラスとオブジェクト
実はすでにVBAのクラスを使う① クラスを使うためのオブジェクトとメソッドの前提知識で詳しく解説しています。エクセルのオブジェクトを例に具体的な解説をしていますので、併せてご覧下さい。簡単に要約すると下記のようになります。
エクセルでは例えば、Sheetsがオブジェクトです。Sheetsとはそこにあるシート(達)そのもののことで、それがオブジェクトです。Sheetsにはいろんな機能がありますよね。削除するとか、追加するとか。そのDeleteとかAddと言ったSheetsのようなオブジェクトが持つ「機能」が書かれたモジュールがクラスです。Sheetsオブジェクトの内容を説明するSheetsクラスにDeleteはどういった機能ですよ、Addはどういった機能ですよ、という説明が書かれています。
Sheets.Addの例を見て分かる様にオブジェクトに「.メソッド名」でそのオブジェクトが持つ機能を使う事ができます。良くある説明で「オブジェクトはモノと言う意味で、Sheets.Addはシートというモノに対してAddという操作をしている」という説明はウソです。Sheetsが持っている機能のAddを呼び出しています。命令している先はSheetsではなくパソコンです。
クラスモジュールの目的
別の見方をしてみます。自分だけの独自の関数をFunctionプロシジャで作る事ができます。これを使う事によって標準プロシジャの中に複雑な処理を書かずに済むようになる、非常に有用なプロシジャです。有用なのでたくさん使ってしまいます。そうするとFunctionプロシジャが増えていきます。後から見た時に、これってどこで使うんだっけ?ってなると困ります。
そんな時、Aと言う処理に使っているFunctionプロシジャを一つにまとめて保存しておけたら便利だと思いませんか?ある処理をするのに使うプロシジャをまとめておくのがクラスである、と言う言い方もできます。
「受注処理」と言う業務があって、その業務の中に「受注金額集計」という処理と「受注登録フォーマット作成」と言う作業があるとします。受注処理クラスに受注金額集計というFunctionプロシジャと受注登録フォーマット作成というSubプロシジャをまとめておく、と言うイメージです。そして使うときに
集計金額 = 受注処理.受注金額集計()
みたいに使う。これがクラスの本質です。
具体的な使い方は下記で説明していきます。
クラスの使い方の手順
それでは具体的な手順を見て行きましょう。クラスの使い方の手順は下記の通りです。
- クラスモジュールでクラスを作る
- 標準モジュールでクラスを元にオブジェクトを作る
- 作ったオブジェクトを標準モジュールで使う
たったの3ステップです。簡単ですね。順に解説していきます。
クラスモジュールでクラスを作る
クラスを作る目的は、Sheetsのようにある機能を持ったオブジェクトを作りたいからです。と言うわけで、今回やりたいことを明確にします。
今回やりたいこと:A1のセルの値をメッセージボックスで表示させる事
クラスモジュールを挿入する
それでは行きます。まずはクラスモジュールを挿入します。挿入⇒クラスモジュール
クラス名をつける
次に、表示⇒プロパティウィンドウでプロパティウィンドウを表示します。
プロパティウィンドウを表示させる理由はクラス名を変えたいからです。オブジェクト名と書いてありますが、これはクラス名です。クラスを作っただけではオブジェクトは生成されません。これのオブジェクト名と書かれているのは「オブジェクトを生成するためのクラス名」の略だと思っておきましょう。
デフォルトでClass1と記入されているので、分かりやすい名前にします。タイトルの約束通り、この記事では日本語で超分かりやすくクラス名を命名します。
クラスから生成したオブジェクトで何をやりたいのかをそのままクラス名にします。だってクラスはオブジェクトの仕様書ですから、やりたいことをクラス名にするのが理にかなっています。このクラス名はオブジェクトの型名になる予定です。
これまでのVBAを思い出して下さい。オブジェクトを変数に入れるときに型を宣言していましたよね。理解がズレないように例を挙げておきますね。
Dim wb As Workbook, ws As Worksheet Set wb = ActiveWorkbook Set ws = ActiveSheet
Asの後のWorkbookとかWorksheetが変数の型の名前です。今回はクラスモジュールを作ってそのクラスモジュールの名前を変えました。これはオブジェクトを代入するための型名を自分で作ったと言う事です。<ここ、超重要>
つまり、クラスモジュールを挿入する事=オブジェクトの型を作る事であり、クラスモジュールの名前を作る事=新しいオブジェクトの型の名前を決める事だったんですね!As WorkbookのWorkbookの部分を自分で作れたんです。「A列の値を操作するクラス」っていうちょっとマヌケな名前だけど。。。
クラスの中身を作る
クラス名(=将来作るオブジェクトの型名)が決まったら、その中身を作っていきましょう、自分で作った型ですよ!ワクワクしますね。
これから作業するのは先ほど作った「A列の値を操作するクラス」と言う名前のクラスモジュールです。
'これは「A列の値を操作するクラス」と言う名前のクラスモジュールに書く Public Function A列の文字を受け取って表示するメソッド() End Function
とりあえず、Functionプロシジャを作りました。Functionプロシジャをマスターしていない人は、まずはVBA Functionプロシジャの使いどころ / 自分独自の関数を作るでFunctionプロシジャを勉強しましょう。
念のため、ざっくりFunctionプロシジャを解説すると、関数を自分で作る、と言う事ですね。普通のエクセル関数のVLOOKUPでは最初に検索された同じ行の値を返しますが、最後に検索された値を返す関数を自分で作る、みたいな。
つまり、値を返す手順を自分で作るのがFunctionプロシジャでした。この部分がメソッドとなります。これからこのメソッド(=オブジェクトの中に書かれた機能、Function=関数)の中身を作っていきます。
中身を追記したのがこちら。たった3行追加しただけです。
Public Function A列の文字を受け取って表示するメソッド() Dim 文字列を受け取る変数_str As String '変数を追記した 文字列を受け取る変数_str = Cells(1, 1) ’代入しただけの部分を追記した A列の文字を受け取って表示するメソッド = 文字列を受け取る変数_str ’関数の戻り値を設定した End Function
「文字列を受け取る変数str」はその名の通り、A1セルの値を一時的に代入するための変数です。今は変数介さずに直せずFunctionに返せばいいのですが、後々威力を発揮するので、いまのうちに変数を用意しておきます。これで、Classモジュールが完成しました。
- クラスモジュールでクラスを作る←今、ココが完了
- 標準モジュールでクラスを元にオブジェクトを作る
- 作ったオブジェクトを標準モジュールで使う
標準プロシジャを用意する
標準モジュールを挿入して、Subプロシジャを作って下さい。(さすがにココは省略でいいですよね)
標準モジュールでクラスを元にオブジェクトを作る
いよいよ、自分で作ったクラスからオブジェクトを作るときが来ました。クラスモジュールは、クラス、つまりオブジェクトが持つ機能(=今回の例ではA1のセルを取得するだけ)を設計するだけでした。実際に使えるようにオブジェクトを作ります!(プログラミングの世界では作成では無く生成と言う言葉を使う様なので、今後、生成すると言います。)
以下は標準モジュールに書きます。(これまでの流れで分かると思いますが、念のため)
Sub クラスを使う標準モジュール() End Sub
ただSubプロシジャを挿入しただけです。中身を書いていきましょう。
変数を宣言する
Sub クラスを使う標準モジュール() Dim A列の値を操作するオブジェクト As A列の値を操作するクラス End Sub
Dim 変数名 As 型名 はおなじみですね。
ついに、自分で作った変数名を宣言する場所が来ました!しかも、その型の名前がさっき作ったクラスモジュール。(Class1とかMyClassみたいなクラス名だから解説ブログなのにわかりにくいんですよ)
この一行が何を意味しているか分かりますか?ちょっと自分で考えてみて下さい。分からなければ例えば、どういうことと同じなのか考えてみましょう。
・
・
・
はい、そうですね、これと同じです。
Dim wb As Workbook
変数名が自分で決められるのは当たり前として、変数の型名を「A列の値を操作するクラス」と言う名前に自分で決めた事の実感が得られてきました!あとは使うだけです。Sheets.Addと同じですね。ただし、今はクラスという仕様書と変数を宣言したにすぎません。オブジェクトの実態を作りましょう!
インスタンスを生成する
先ほどから「オブジェクトを作る」といってきました。オブジェクトと言って何ら問題はありません。ただ、クラスから生成されたオブジェクトのことを特に「インスタンス」と呼ぶ風習があります。覚えておくと便利です。覚えていなくてもVBAでは問題ありません。(ちなみに、今回、生み出すオブジェクトはまさに自分で定義したクラスから生み出すオブジェクトなので、「インスタンス」と呼ぶにふさわしいモノ(=オブジェクト)です。Sheetsはオブジェクトですが、自分で生成していないので、インスタンスではありません)
それではインスタンス(=自分で作るオブジェクト)の生成です。
Sub クラスを使う標準モジュール() Dim A列の値を操作するオブジェクト As A列の値を操作するクラス 'さっきの定義したところ Set A列の値を操作するオブジェクト = New A列の値を操作するクラス '←今ココ End Sub
おめでとうございます。インスタンスの生成完了です!オブジェクトを変数に格納するので当然、”Set”がついています。注目すべきはNewです。VBAでは、クラス名の前にNewをつけてオブジェクト型の変数に代入することで新たなインスタンスを生成できます。<超超重要>
- クラスモジュールでクラスを作る
- 標準モジュールでクラスを元にオブジェクトを作る ←今、ココが完了
- 作ったオブジェクトを標準モジュールで使う
生成したインスタンスを使う
Sub クラスを使う標準モジュール() Dim A列の値を操作するオブジェクト As A列の値を操作するクラス Set A列の値を操作するオブジェクト = New A列の値を操作するクラス MsgBox A列の値を操作するオブジェクト.A列の文字を受け取って表示するメソッド End Sub
MsgBox の行を1行加えただけです。MsgBoxの引数に注目してみましょう。
A列の値を操作するオブジェクト.A列の文字を受け取って表示するメソッド
となっています。これは、生成したインスタンスですね。「A列の値を操作するクラス」という型のオブジェクトでした。「A列の文字を受け取って表示するメソッド」は「A列の値を操作するクラス」のクラスモジュールでFunctionプロシジャで作りました。
- クラスモジュールでクラスを作る
- 標準モジュールでクラスを元にオブジェクトを作る
- 作ったオブジェクトを標準モジュールで使う←今、ココが完了
ここまでできたらF8を押して、一行ずつ実行してみましょう。MsgBoxを実行した瞬間にクラスモジュールに移り、メソッド(=クラスモジュールのFunctionプロシジャ)が実行する様子が確認できます。
今回は値を戻したいだけなので、Functionプロシジャでメソッドの内容を記述しましたが、Subプロシジャでメソッドを記述する事もできます。
これから、この「A列の値を操作するクラス」を充実させながら、クラスモジュールに慣れていきましょう。
先にクラスモジュールの実務的な使い方を見たい方は、VBAのクラスを使う② ユーザーが選択したファイルを開く実務的なオブジェクトを生成するをご覧下さい。
それでは、頑張っていきましょう。
<関連記事>
<お知らせ>
Excel VBAでクラスやオブジェクトの概念と使い方を丁寧に解説し、ワンランク上の実力を目指すガイドを書きました。この本で本物の実力を身に付けて一皮むけてみませんか?
books.rakuten.co.jp