それわVBA案件ですね

エクセルVBAネタを書いています

インターフェイスをかじってみた

今回も書きかけのシリーズ記事とは違うネタです。
んが、決して飽きたわけではありませんのです。
こんちくわ|ω・)ノ

さて、ノンプロ研の方がノンプロSlackVBAインターフェイスを使ったコードについて何か良い方法はないかなぁといった書き込みがありました。
インターフェイスについてはその書き込みをした方から以前いろいろと教えていただいていたのですが、実際にコードを書いたことがなかったので、勉強がてらチャレンジしてみることにしました。
それで、一定の理解を得ることができたので備忘録的な意味も含めて記事に残そうと思います。

でわいきます ̄▽ ̄)

目次

VBAインターフェイスって...

  • ナニ?
  • 何ができるの?
  • どうやって書くの?

  • まとめ



インターフェイスってナニ?

改めてググってみたら、thomさんの記事がHitしました。

thom.hateblo.jp

もうここにすべてが書かれているので私が改めて記事にする必要などないような気がしますが、あくまで自分自身の学習のためですので、お付き合いくださいましまし。

で、私なりのインターフェイス捉え方ですが、
VBAでいうインターフェイスとは、1本でいろんな家電を操作できる共通リモコンのようなもの だなぁと思いました。

つまり共通リモコンの各種操作ボタンは1組しか用意されていないけれども、リモコン上の切り替えスイッチを切り替えることで、テレビが操作できたり、ビデオが操作できたりするようになる。

もう少し突っ込むと、
テレビやビデオが電源ON/OFFを認識する信号は異なるけれども、1つしかないリモコンの電源ON/OFFボタンを押したときに発射される信号は、リモコンの手元の切り替えスイッチ操作によって、テレビやビデオに合わせて変化させることができる。

そう、インターフェイスとわ
入り口は1つだけど出口を複数に変化させる仕組み

なのだなと思いました。



VBAインターフェイスで何ができるの?

コレ重要ですよね。

入り口は1つだけど出口を複数に変化させる仕組み という概念から、いまのところ思いつくのは、

例えば、

  • エクセルでワークブックを開くコマンドは、Workbooks.Open を使いますが、ワードVBAでは、Documents.Open、パワーポイントではPresentations.Openとなるように、同じ操作でも言語によってコマンドは変わるものです。
    コレを一括して同じ(例えば)FileOpenみたいな共通コマンド化してつかうことができる

  • 異なるクラスモジュールに設定したそれぞれ機能が異なるメソッドセットを共通のメソッド名で使い分けるようになる。

っていう感じでしょうか。
他にもありそうですが、経験不足なのでちょっと思いつかないですね^^;



どうやって書くの?

インターフェイスを実装するには、クラスモジュールを使った記述が必要になります。

クラスってナニ?については前回の記事で触れましたが、概念のみ(しかも個人的な)で、具体的な書き方については一切触れていませんので、そこのあたりはコチラのシリーズ記事 tonari-it.com

を参考にしていただけると良いかと思います。。
 


と、いうわけでどう書くかですが、
ココでは例として、異なるクラスモジュールに設定したそれぞれ機能が異なるメソッドセットを共通のメソッド名で使い分ける方法(上に書いた使用例の2番目ですね)について書きます。

別々のクラスモジュールにそれぞれ定義した3つのメソッドを使い分ける

クラスモジュールを合計4つを挿入して以下のようにオブジェクト名を設定します。

[f:id:FukuCyndiP:20191022161819p:plain:w350

上からそれぞれ異なるメソッドセットを入れるFuncSetA, FuncSetB, FuncSetCと、共通リモコンインターフェイスとして共通のメソッド名を定義するInterFaceAです。

通化したいメソッド名をInterFaceAに定義します

(クラスモジュールInterFaceAに記述)

Option Explicit
'インターフェイスで共通化したいメソッドを記述します
'名前のみでおk

Public Sub Greet()
End Sub

Public Sub Response()
End Sub

ここでは名前だけで、中身は必要ありません。

メソッドセットを作ります

ココでは各メソッドの内容も含めてコードを記述していきますが、以下の3つのお約束に従ってコードを書かなくてはいけません

(クラスモジュール: FuncSetAの内容)

Option Explicit

Implements InterfaceA

Public Sub InterfaceA_Greet()
  MsgBox "おじゃまします`"
End Sub

Public Sub InterfaceA_Response()
  MsgBox "どうぞ~`"
End Sub


  1. モジュールの宣言部に”Implements"+実装するインターフェイス名を記述する( Implements InterfaceA)
  2. 各メソッド名は実装したいインターフェイス名と(クラスモジュールInterfaceAで)宣言したメソッド名をアンダースコア( _ ) でつないだものにする
    ( InterfaceA_Greet(), InterfaceA_Response()にします)
  3. メソッドはInterfaceA で宣言した共通化したいメソッドをすべて使います(足りなくても、多すぎてもエラーになります)



上記お約束に従って残りのモジュール(FuncSetC, FuncSetCにもメソッドを記載します)

(クラスモジュール: FuncSetbBの内容)

Option Explicit

Implements InterfaceA

Public Sub InterfaceA_Greet()
  MsgBox "じゃまするでぇ"
End Sub

Public Sub InterfaceA_Response()
  MsgBox "じゃまするんやったら、帰って~
End Sub



(クラスモジュール: FuncSetCの内容)

Option Explicit

Implements InterfaceA

Public Sub InterfaceA_Greet()
  MsgBox "おじゃまします・・・か?"
End Sub

Public SubInterfaceA_Response()
  MsgBox "なんで聞くねん! 「か」いらんやろ!"
End Sub



これでインターフェイスを使う準備は完了ですので、これを使うコードを書いていきましょう

インターフェイスを使うコードを書く

これは標準モジュールに書きます。

Option Explicit

Sub Ippann()
'クラスモジュール名(FuncSetA)を変えることで
'Greet, Response メソッドの処理内容が変化します

  Dim c As InterfaceA
  Set c = New FuncSetA
  Call c.Greet
  Call c.Response

End Sub



ココではInterfaceA(型?)で宣言した変数cを準備して、クラスモジュールFuncSetAから生成したオブジェクト(インスタンス)を代入しています。

このプロシージャを実行すると、

f:id:FukuCyndiP:20191022185408p:plain:w200

f:id:FukuCyndiP:20191022185422p:plain:w200

と、クラスモジュールFuncSetAに準備した Greet(), Response()メソッドが無事実行されました。

じゃぁ、残りのメソッドに切り変えるにはどうするかというと、Set c = New FuncSetAのクラスモジュール名FuncSetAの部分を書き換えればおkです。


Set c = New FuncSetBと書き換えたなら、

f:id:FukuCyndiP:20191022190256p:plain:w200

f:id:FukuCyndiP:20191022190309p:plain:w250



Set c = New FuncSetBと書き換えたなら、

f:id:FukuCyndiP:20191022190502p:plain:w200

f:id:FukuCyndiP:20191022190518p:plain:w300

となります。
このようにインターフェイスを使うことで、入り口は1つだけど出口を複数に変化させる仕組み を作ることができましたね

まとめ

今回は入り口は1つだけど出口を複数に変化させる仕組みとしてVBAで作成するインターフェイスについて書きました。
この仕組みをどのように応用するか?ということについては、私にはまだまだアイデア不足なところもあります。ただ、入り口は1つだけど出口を複数に変化させる仕組みがVBAで作れるということだけアタマの隅に置いておけば、コードのロジックを考える際の引き出しの一つとして利用できる場面もあるかと思います。
すでに他のブログでもいくつかの使い方が紹介されていますので、参考にしてみてはいかがでしょうか?

thom.hateblo.jp

akashi-keirin.hatenablog.com



でわまた~ ̄▽ ̄)ノシ