他ワークブックやアドインのプロシージャ呼び出し

「プロジェクト」を超える呼び出し方法です。
なぜ、こんなことが必要なのでしょうか!?   マクロ初心者の方には難しい話かもしれませんが、なぜ必要かも説明します。
当サイトでは作成したプログラムの「主たる部分」の置き場所を「一元化」することをお勧めしています。 ここでの説明はそのための手段についてなのですが、仕組み的なタイトルだとこのようになってしまいます。



便利な機能が実装されたExcelワークブックだったら、利用部署では他の担当者でも使いたくなるものです。 いつの間にかコピーされたものがあちこちに持ち出されてしまうかもしれません。



こうして配布されたマクロについて、後から不具合が見つかったり、機能追加の要望があったりすることは充分に起こりうることです。



こんなことを想定すると、早い段階で対応を考えた方が良いことはご理解いただけると思います。
このページの最後の方で詳しく説明しています。

「他ワークブックのプロシージャ呼び出し」を試してみます。

アドイン化の実験

まず、このように新しいワークブックを2つ開きます。新規にExcelを開いたところから行なうと、「Book1」「Book2」となると思います。
    ・「Book1」:利用者がデータを登録する「データブック」
    ・「Book2」:「マクロブック(又はアドイン)
という想定です。
試す内容は通常操作する「Book1」から、「Book2」にあるプロシージャを起動させることにします。







次にVBEを開きます。

Visual Basic Editorを開いたところ

このように左のプロジェクトエクスプローラには「Book1」「Book2」が表示され、表示メニューから「イディミエイト ウィンドウ」を選択して、開いているワークブックのカウントを見ると、「2」と表示されます。
Book1」「Book2」の中にはそれぞれ「Sheet1」が表示されます。 一般のExcelの設定だとこの他に「Sheet2」「Sheet3」が表示されると思います。 「Sheet2」「Sheet3」はそのままでも構いません。







ここで、「Book2」をマクロブックかアドインに見たてますが、まず、簡単なマクロを仕込んでおきます。

Book2にマクロを仕込む。

Book2」を選択して、Module1(標準モジュール)を追加して、メッセージ表示だけの簡単なマクロを書き込んでおきます。







次に「Book2」をアドインに変更します。
用途としてはマクロブックのままでも良いのですが、このままだとExcelの操作上で「Book2」が見えてしまい、 先ほど作成した「Book2」のマクロもそのまま起動できてしまいます。
「他ワークブックのプロシージャ呼び出し」の動作確認のためには「Book1」側から「Book2」側のマクロが呼び出せることを確認するので、 アドインに変更することで「Book2」がExcel画面上から見えなくなります。

プロパティウィンドウを表示

「プロパティウィンドウ」を表示させて、プロジェクトエクスプローラで「Book2」の「ThisWorkbook」をクリックします。プロパティに表示される項目の中にIsAddinプロパティがあり、「False」になっています。





これを「True」に変更すればアドインとして機能します。

IsAddinプロパティをTrueに変更した。

True」に変更しても、VBE側では何も変化が起きませんが、Excelのウィンドウに戻ると、

Book2が消えた

このように、「Book2」は消えてしまいます。(ウィンドウメニューにも表示されません。)







作成したマクロはどうなったかというと、

マクロの消えてしまった。

Book2」で作成されたマクロは表示されなくなりました。では「Book1」側からどのように「Book2」のマクロを動作させるのでしょうか。





VBEに戻ると、「Book2」は閉じてしまったのではないことが確認できます。

Book1にマクロを追加する。

では、「Book1」の方に標準モジュールを追加して、Runメソッドで「Book2」側の「TEST1」プロシージャを起動させてみましょう。このように記述できたら、もう一度Excelのウィンドウに戻ってマクロを起動してみて下さい。

Book2のTEST1プロシージャが起動された。

このように、アドインとなった「Book2」のプロシージャ「TEST1」が動作したのが判ります。

Runメソッドについて



「他ワークブックのプロシージャ呼び出し」にはRunメソッドを用います。
上のサンプル(2つ前の画像)では「Book2」側のプロシージャ呼び出しはこのように記述していました。

Application.Run Macro:="Book2!TEST1"
これは「Book2」側のプロシージャが引数や戻り値がない場合の書き方になります。
この第1引数が実行するプロシージャの指定となり、ブック名とプロシージャ名を"!"を挟んで指定します。
ここでは新規ワークブックでの動作確認であったため拡張子がありませんが、通常は拡張子を含めて指定します。 この第1引数は文字列の指定であり、コンパイル段階ではチェックを受けません。 実行時に存在等のチェックを受けることになります。
この指定でのブック名に当たるワークブック又はアドインは開いている必要があります。
なお、「Macro:=」は省略できます。







呼び出すプロシージャに引数がある場合は、第2引数以降で指定します。

Application.Run "Addin.xlam!Macro1", [第1引数], [第2引数], ...
あるいは、Callステートメントでプロシージャ呼び出しであることを明示します。

Call Application.Run("Addin.xlam!Macro1", [第1引数], [第2引数], ... )







呼び出すプロシージャがFunctionプロシージャの場合は戻り値を受け取ることができます。

[戻り値] = Application.Run("Addin.xlam!Macro1", [第1引数], [第2引数], ... )







「他ワークブックのプロシージャ呼び出し」での実装時の注意としては、引数、戻り値にオブジェクト型が指定できないことがあります。
アドイン又はマクロブック側からすると、ユーザーが利用しているワークブックやワークシートを引数で受け渡してほしいのですが、 これができないのでワークブック名、ワークシート名を引数で渡して、アドイン又はマクロブック側でオブジェクトを取り直す処置が必要です。

必要な理由と実装する場合の要点を説明しておきます。



このページ先頭のコラムに書いた通り、このような処置を行なうのは「データ」と「仕組み(マクロ)」を分離させて、 「仕組み(マクロ)」の変更を柔軟に行なえるようにしたいからです。



Excelワークブックには以下のようなものが格納され、1つのファイルとして保存されます。
  • ワークシート上の視覚的なデザイン
  • 書式・計算式・コメント・入力規則等
  • ワークシート上の視覚的なデザイン
  • マクロ(マクロ有効ブック時)
  • 利用者がワークシート上に入力したデータ
つまり「仕組み」と「データ」が混在した状態で1つのファイルとして保存されるわけです。
例えば「勤務表」だったら個人別月別にファイルが分かれるので、月ごとに社員の人数分のファイルが作成されることになります。 年間だったらさらに12倍である上、数年分は保存させておく必要があるはずです。
社員が100人、保存年数が5年だったら6000ファイルということになります。



各ファイルで内容が異なるのは上の枠内の赤で示す「利用者がワークシート上に入力したデータ」だけでそれ以外は固定的な「仕組み」です。
ここで、この「仕組み」が全く変動がないのであれば良いのですが、利用度が高い「仕組み」ほど改廃が発生するものです。
それは「不具合対応」だったり、「機能要望」だったり、「勤務表」のようなものだと「法律改正要件」だったりします。



さらにマクロの規模が大きい場合は、多数ファイルが作成されるワークブックに格納するより、1つだけ共通フォルダに置いておけば済む今回の「分離方式」の方がリソースの容量負担軽減にも寄与できます。



既に多くのファイルにコピーされてしまっているとか、保存先が多岐に渡っているとか、そのような状況になってしまってから 「仕組み」の変更が発生した時に作成済みの多数のファイルにも同じ変更が反映されるように、 早い段階で対応を考えておく必要があるだろうと言うのがここでの提案です。 以前から「配布の問題」でも提起していることですが、VBA初心者にも必要なことなので こちらにも説明を追加しています。







お勧めする方法は以下のようなものです。
  • 主要なマクロコードをアドインやマクロブックに分離する
  • このアドインやマクロブックは社内共通のネットワーク上の特定フォルダに配置(1つだけ)
  • 配布する各ワークブックは起動時に裏で上記のアドインやマクロブックを開いてマクロを用いる
      ⇒配布する各ワークブックには上記のアドインやマクロブックを開く部分とそのマクロを起動する部分だけ記述する







この「ワークブック」と「アドイン(又はマクロブック)」の内容的な分担は以下のようになります。

主要プログラムをアドインに収容する。

この図だと「ワークブック」と「アドイン(又はマクロブック)」が1対1に見えてしまいますが、 「アドイン(又はマクロブック)」の方は1つの仕組みで1ファイル(固定ファイル名)です。
「ワークブック」の起動マクロで「アドイン(又はマクロブック)」を開く想定ですが、 「読み取り専用」で開くなら複数の「ワークブック」から同時に開いて利用できます。 また、「アドイン(又はマクロブック)」は基本的にマクロのみであって、利用中に保存することはありません。



社内のネットワーク環境によりますが、例えば全社(全部署/全事業所)から参照できる共通ファイルサーバがあるなら、 その中に特定フォルダを割り当てて「アドイン(又はマクロブック)」は1つだけ配置すれば済みます。







本ページの最初の方のテストで行なったように「ワークブック」にも多少のマクロは残ります。
ですが「ワークブック」に必要となるマクロは、
    ・起動時に「アドイン(又はマクロブック)」を「読み取り専用」で開く
    ・必要なアクション時に「アドイン(又はマクロブック)」のマクロを呼び出す
というだけに追い込めるはずです。
つまり、業務要件などで変更が発生することがほとんどないという状況が作り出せることになり、 「アドイン(又はマクロブック)」のマクロの変更については新たなバージョンのものを上書きすれば良いということになります。







[アドイン・マクロブック方式でない方法は?]
「配布の問題」の先頭ページの下の方「バージョンの判定や入れ替え手段」にまとめてあります。