VBAでクラスモジュールを使うわけ

記事
IT・テクノロジー
さて、先日使い倒したChatGPTで、VBAのクラスモジュールの制限の事を聞いたら、こんな丁寧で詳しい回答が返ってきました。

VBAで作成するクラスモジュールは、Javaなどのオブジェクト指向言語で作成するクラスと比較して、以下のような制限があります。

1.クラスの継承の制限: VBAでは、クラスの継承をサポートしていません。そのため、クラスの再利用性が低下する可能性があります。
2.ポリモーフィズムの制限: VBAでは、クラスのメソッドのオーバーロードやオーバーライドをサポートしていません。そのため、同じ名前のメソッドに対して、異なる引数を設定することができないため、ポリモーフィズムの実現が困難になる可能性があります。
3.インターフェースの制限: VBAでは、インターフェースを明示的に定義することができません。そのため、クラスの機能やメソッドが不明瞭になる可能性があります。
4.例外処理の制限: VBAでは、例外処理をサポートしていますが、Javaなどの他のオブジェクト指向言語に比べて、精度が低く、エラーメッセージの表示が不明瞭であるため、開発者にとっては制限に感じられるかもしれません。

以上のように、VBAで作成するクラスモジュールには、オブジェクト指向プログラミングにおける一般的な機能が制限される可能性があるため、開発者は注意が必要です。

固まってしまいました。

特に最後の1文、「開発者は注意が必要です」ではなく、「開発者は工夫が必要です」では???

他にツッ込みたいところがいくつもありましたが、ここでは止めておきます。

VB及びVBAのクラスモジュールの最大の制限、継承ができない事とよく言われますが、

特に、Excelのマクロのように、大掛かりでない小規模システムにおいては、クラスを継承したり、インターフェースを作るほどの必要がある事はあまりなく、

それよりも、クラスの初期化にパラメータが渡せないのが、一番大きな制約に感じます。

(ChatGPT君ご指摘のポリモーフィズムの制限の1例に当たります)

とはいえ、私はマクロを組む際に、クラスモジュールを多用し、

便利だけれど扱いが面倒なテーブル処理をするための共通クラスも生成し、

多くのマクロで再利用し、開発効率が劇的にアップしました。

多々制限がありつつ、クラスモジュールを使うメリットとして、私が思う所としては、

1)変数をクラス内で定義すれば、クラス内のメソッドから自由に初期化、参照、更新できる。個々のメソッドでパラメータを渡す必要がない。

2)メソッド名はクラス内で重複しなければ、他のモジュールと被っていてもよい。従って、saveとかfindとかシンプルな名前が使える。

ExcelVBAにおける典型的クラスモジュールの作り方としては、ワークシートを持たせて、ワークシートへの様々な処理、検索、データ編集、セルの書式設定の処理を必要に応じてメソッド追加して、マイワークシートクラスを作る事です。

これによる、特定のワークシートだけでなく様々なワークシートの処理を共通化できます。

どのワークシートの処理をするか最初に指定しておき、その後はfindとかaddとかsetColorとかのメソッドではワークシートをパラメータに渡す必要はなく、その機能に必要なパラメータを渡せばよいだけになります。

この、最初にワークシートを指定するのに、クラスの初期化メソッドClass_Initializeにワークシート名をパラメータで渡せればいいのですが、それができないので、initとかいう初期化用のメソッドを自分で用意し、そのクラスの処理をする時には必ず最初にこのメソッドを呼ぶように外側のモジュールで行わなければなりません。またクラス内でもこの初期化が行われなかったときの対応も必要になります。

継承ができないのは、さほど不便には感じないですが、初期化でパラメータが渡せないのは、かなり不便です。

もう一つ、クラスモジュールの大きなデメリットといえば、初期化のパラメータの他に、デバックでエラーが発生したときに、クラスの中コードに止まってくれない事です。

例えば、以下のようなコードがあったとして、
Module1
sub Test
  dim smp as new clsSample
  if (smp.chek()=0) then
    msgbox "チェック結果はありません"
   end if
end sub

class clsSample
function check() as integer
  check="A"
end function

Integer型の関数に文字を入れようとしているので、型変換エラーが発生しますが、check="A"の行には止まらず、メソッドを呼んでいるsmp.check()で止まります。

実際に作成するマクロでは、メソッドの処理は何10行もあり、呼んだメソッドからさらに別のメソッドを呼ぶことも多々あるので、標準モジュールにしか止まらないというのは、かなり不便です。そこから、本当にエラーが起きているのがどこかステップ実行して探さなければなりません。

こんなデメリットがありつつも、やはりクラスモジュールにするとデータ付きで共通化できるので、開発効率は上がり、何より仕様変更がやりやすいメリットは、これらのデメリットを上回り、愛用しています。


サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す