読者です 読者をやめる 読者になる 読者になる

【VBA】動的に参照設定を変更する(1)

ThisWorkbook.VBProject.Referencesで今開いているブックの参照設定に関わるオブジェクトを取得することが出来ます。

こんなコードを書けば、今参照設定されているライブラリを列挙することも出来ます。(※事前にマクロのセキュリティに関する設定が必要)

'アーリーバインディングする場合は「Microsoft Visual Basic for Applications Extensibility 5.3」を参照設定に追加
Dim ref As Reference
    
For Each ref In ThisWorkbook.VBProject.References
    Debug.Print ref.Description
Next ref

で、ReferencesのAddFromFileメソッド、AddFromGuidで参照設定の追加を、Removeで参照設定の解除を行うことが出来ます。こいつらを使えばえっちらおっちらと参照設定を動的に変更できます。

とは言え、アーリーバインディングで開発を進め、配布するモジュールに組み込んでおいて「コードの実行前に参照設定が可能かどうか調べて必要であれば動的に追加」みたいなことは出来ません。理由は簡単で、コンパイルエラーになるためそのコードがまず動かせないからです。

ただ、「開発時は参照設定出来てたけど本番環境だと参照不可になるかもしれないし、参照不可だったら別の参照設定をしたい」ぐらいなら、出来るかもしれません。試せる環境がないです。

要は、こんなことも出来るよ、程度のものでしかありません。

Referencesから呼び出せるメソッド

とりあえず各メソッドのドキュメントを読んでみましょう。ヘルプファイルから引用してみます。

AddFromFile メソッド

構文

object.AddFromFile(filename)

AddFromFile メソッドの構文は、次の指定項目から構成されます。

指定項目 内容
object 必ず指定します。オブジェクトへの参照を表すオブジェクト式を指定します。
filename 必ず指定します。プロジェクトまたはモジュールに追加するファイルの名前を表す文字列式を指定します。ファイル名が見つからず、パス名が指定されていない場合は、Microsoft Windows の OpenFile 関数が使われ、決められた順序でフォルダ内のファイルが検索されます。

普通にフルパスでファイル名を渡してあげればいいです。

AddFromGuid メソッド

構文

object.AddFromGuid(guid, major, minor)

AddFromGuid メソッドの構文は、次の指定項目から構成されます。

指定項目 内容
object 必ず指定します。オブジェクトへの参照を表すオブジェクト式を指定します。
guid 必ず指定します。参照の GUID を表す文字列式を指定します。
major 必ず指定します。参照のメジャー バージョン番号を表す長整数型 (Long) の値を指定します。
minor 必ず指定します。参照のマイナ バージョン番号を表す長整数型 (Long) の値を指定します。

ふーんって感じですね。

Remove メソッド

構文

object.Remove(component)

Remove メソッドの構文は、次の指定項目から構成されます。

指定項目 内容
object 必ず指定します。オブジェクトへの参照を表すオブジェクト式を指定します。
component 必ず指定します。LinkedWindows コレクションには、オブジェクトを指定します。References コレクションには、タイプ ライブラリまたはプロジェクトへの参照を指定します。VBComponents コレクションには、クラス モジュール、フォーム、または標準モジュールを表す定数を指定します。VBProjects コレクションには、スタンドアロン プロジェクトを指定します。

componentが何を言ってるのかわかりにくいですが、要はThisWorkbook.VBProject.Referencesをforeachで取得したReferenceをそのまま渡してあげればOKです。

参照設定とCreateObjectの仕組み

さて、ファイルのフルパスはともかく、なぜGUIDを渡して参照設定が出来るのでしょうか。

そもそもVBEで参照設定するときに出てくる一覧はどこから取ってきてるのでしょうか。

答えはレジストリの中にあります。HKEY_CLASSES_ROOTのTypeLibの中を見るとmajor + . + minorという規約でつけられた階層があります。ここの値がエディタの参照設定で表示される名称です。さらにその中の0という階層の中にwin32/64の階層があり、そこの値がファイルパスになっています。

逆に言えば、「参照設定で表示される名称」さえわかれば(効率は死ぬほど悪いけど)レジストリをチェックしてどのファイルを参照設定に追加すればいいのかもわかるわけです。

実はCreateObjectも近いことをやっています。CreateObjectで渡された文字列とHKEY_CLASSES_ROOT\CLSIDに登録されているGUIDをマッピングし、必要なライブラリのパスを取得しているのです。この辺の仕組みはこの記事が詳しいので興味がある人(いるのか?)は読んでみてください。

まとめ

さてさて、これで参照設定を動的に変更するために何が必要なのかわかってきました。

  • ファイルのフルパス
  • 対象のGUID+majorバージョンとminorバージョンの値
  • 参照設定のダイアログに出てくる名称
  • CreateObjectで使える文字列

このどれか一つでもあれば自由自在に参照設定を変更できそうです。ただ、死ぬほどしんどいので具体的にどうやるかはまた後日にします。

[2014/07/02追記]

完成したのにリンクを張っていませんでした。