VBAでインターフェースを使って引数付きのコンストラクタを実現する

元ネタはこちら

参考サイト

愚者の経験 – コンストラクタで引数を入れたい
https://foolexp.wordpress.com/2012/02/21/%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF%E3%81%A7%E5%BC%95%E6%95%B0%E3%82%92%E5%85%A5%E3%82%8C%E3%81%9F%E3%81%84/

愚者の経験 – クラスモジュールにも「規定のインスタンス」
https://foolexp.wordpress.com/2012/02/24/%E3%82%AF%E3%83%A9%E3%82%B9%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%81%AB%E3%82%82%E3%80%8C%E6%97%A2%E5%AE%9A%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%80%8D/

t-hom’s diary – VBAでインターフェースを使って引数付きのコンストラクタを実現する。
https://thom.hateblo.jp/entry/2015/02/15/012503

VBAでインターフェースを使って引数付きのコンストラクタを実現するやり方を模索していたのですが、かなり強引な方法ですが、ほぼやりたいことができたのでやり方を公開します。t-homさんも言っていますが疑似引数付コンストラクタです。(裏技的な感じがハンパないです・・・。)

結果どうなったか

以下、記述にて疑似コンストラクタの記述ができるようになりました。IConstructor クラスを追加するだけで、標準モジュールを不要にしました。

IConstructorは初期のインスタンスをあたえて、そのままクラス名で呼べるようにします。New したクラスと引数を指定します。引数の指定は好みですが、2つのInstancingメソッドでの引数の受け渡しでParam Array が使いづらいので複数指定の時にはArrayで渡すようにしました。

以下、実現方法です。

Interfaceクラスの説明

IConstructor というInterfece クラスを1つ作成します。

キモは「Attribute VB_PredeclaredId = True」でクラスに規定のインスタンスを与えることです。
規定のインスタンスとはクラスをNewしなくても、インスタンスが1つ生成され、クラス名でメンバにアクセスが可能になります。他言語でいう Static なクラスです。

このプロパティはプロパティウィンドウでは書き換えられないので一度、EXPORTした後、値をTrueに変更、インポートします。
本来のこのクラスは Interface に使用するので、Instancing メソッドの中身を書く必要はありません。しかし、このクラス自体は普通のクラス扱い(呼び出し先はImplementsを書くけど)
なので、コンストラクタに引数を渡すヘルパー関数として利用します。参考にしたサイトでは標準モジュールを利用していましたのでその改善になります。

以下、Export した状態のクラス。8行目を True にする。

コンストラクタを作成したクラスの説明

こちらはサンプルのクラスとして、以前作っていた StringBuilder クラスですが、これにInterfaceを用いて引数付のコンストラクタを作成します。
「Implements IConstructor」を記述し、作成される「IConstructor_Instancing」メソッドの中に初期化の内容を記述します。

呼び出し側と呼び出されたコンストラクタの引数が一致しているため(そもそもそれがInterfaceの役割ですが)イイ感じにリンクできている感じです。
もうちょっと Param Array 同士の受け渡しがうまくいけばなぁ~。という感じ。

サンプルダウンロード(constructor.xlsm)

ABOUTこの記事をかいた人

はてなブックマークで驚愕の1600越えを記録した伝説が今明らかに! エクセル方眼紙 四天王の1人(ほぼ最弱)窓の杜大賞2014 大賞受賞! Excelを便利にする250以上の機能を体系化したアドインはこちらです。