HighOctaneFuel

C#でExcelで使えるマネージドライブラリを作ってみよう


今日(2013/10/28)、私の趣味の一つであるトレイルランニングに関して、少し動きがありました。
というのも、目標にしていた筑波山トレイルラン大会の申し込みが締め切られてしまったのです。
10/31までとしてあったので、コースを念入りに試走してからと思い、申し込みを控えていました。
残念で仕方ありません。
しかし、来年こそはと思いながら、他の大会も視野に入れつつ、まず、体重を落とすところから始めたいところです。


さて、本題に入ります。
今回は、VBAの本題からは少し外れます。
最終的には、VBAに回帰しますが、C#でライブラリを作ることが主題となっています。

ネタ元はこちらのサイトを参考にさせていただきました。
ありがとうございます。

この課題を通して、マネージドDLLのレジストリへの登録の仕方、Excel VBA側での参照設定の方法について学んでいただければと思います。
頑張ってまいりましょう!!

1.Visual Studio でライブラリを作る

ライブラリの作成に必要なファイル群:
ExcelExLibrary.cs(クラス)
IExcelExLibrary.cs(インターフェース)

上記2つのファイルを記述していきます。
まずは、プロジェクトの作成からです。
下記を参考にC#のクラスライブラリを選択します。



クラス名を"ExcelExLibrary.cs"とします。

ファイルの[名前の変更]をすると、クラスの定義などのファイル内に記述された文字列も置き換わります。Class1→ExcelExLibraryのように…。



setNameメソッドとgetNameメソッドを持った単純なクラスです。
注意していただきたい点は、2つです。

一つ目は、usingディレクティブの一番最後の行。
System.Runtime.InteropServicesの記述を付け足すこと。(参照設定は不要です)

二つ目は、クラスの定義の前に属性を記述することです。
2行あります。
[ComVisible(true)]
ComVisible属性」は、マネージ型が COM から参照できることを示します。true を選択してください。
[ClassInterface(ClassInterfaceType.None)]
ClassInterface属性」は、COM クライアントが使用するインターフェースは、明示的なインターフェースの定義が必要とされることから記述を要します。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Runtime.InteropServices;

    namespace ExcelLibraryVer1
    {
        [ComVisible(true)]
        [ClassInterface(ClassInterfaceType.None)]
        public class ExcelExLibrary:IExcelExLibrary
        {
            String str;

            public void setName(String str)
            {
                this.str = str;
            }

            public String getName()
            {
                return "こんにちは " + str + " さん!";
            }
        }
    }
    

インターフェース名を"IExcelExLibrary.cs"とします。





ファイルの構成は下図のようになっているでしょうか?



例によって、usingディレクティブの一番最後の行。
System.Runtime.InteropServicesの記述を付け足すこと。(参照設定は不要です)
以下をクラスの定義の前に属性を記述します。
[ComVisible(true)]
ComVisible属性」は、マネージ型が COM から参照できることを示します。true を選択してください。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Runtime.InteropServices;

    namespace ExcelLibraryVer1
    {
        [ComVisible(true)]
        public interface IExcelExLibrary
        {
            void setName(String str);
            String getName();
        }
    }
    

最後に、ExcelExLibraryクラスにこのインターフェースを実装しますこちらのコードを参考に、
クラスの定義(public class ExcelExLibrary:IExcelExLibrary)左の赤記を付け足します。

ExcelExLibraryとIExcelExLibraryのファイルの記述が完了したところで、
ビルドしてください。
正常にビルドが完了したでしょうか?

2.アセンブリ登録する

これから、下記のフォルダにおいて作業を行うことを仮定して話を進めます。
D:\...\ExcelLibraryVer1\ExcelLibraryVer1\bin\Debug

下に示すファイルが作成されていることを確認してください。
D:\...\ExcelLibraryVer1\ExcelLibraryVer1\bin\Debug\ExcelLibraryVer1.dll

ライブラリを利用するに当たって、アセンブリ登録をしなくてはならないようです。
こちらに詳細が記載されておりますので、参考までに…「マネージ コンポーネントを COM クライアントからアクティブにするには、Windows レジストリに登録する必要があります。」

下記、スクリプトを参考に登録用と登録解除用の二つのcmdファイルを作ります。

[reg.cmd](登録用)


[unreg.cmd](登録解除用)


準備ができたら、reg.cmdファイルを実行し、レジストリに登録を行います。
その際の注意点として、管理者権限で実行することを忘れないでください。

エクスプローラより、[ファイル]-[コマンドプロンプトを開く]-[コマンドプロンプトを管理者として開く]
そして、ユーザーアカウント制御が「はい」か「いいえ」を聞いてきますので、「はい」を押下しプロンプトを開きます。
開いた、プロンプトに先ほどのcmdファイル(reg.cmd or unreg.cmd)名を入力し実行するという段取りです。



[登録]



[登録解除]


3.VBEにコードを記述する


ここでは、Excel VBAから参照可能なライブラリファイルの設定の方法を説明します。

VBAから、今回作成した"ExcelLibraryVer1"を利用するためには、「参照設定」することにより可能になります。



この参照設定はなぜ必要なのかという疑問にお答えすべく、いろいろ考えてはみたのですが、なかなか上手な例示がなく、
その中でも、こんな例えはどうかと考えてみました。

映画館の入館券を思い出してください。 入館券は、そのものには力がありませんが、いざ、劇場で映画を見るとなった時、劇場のスタッフさんに見せたり、若しくは自動改札機に通したりして、初めて映画を見るために入場することが可能となります。
これを参照設定に当てはめてみましょう。

クラス(入館券)は、VBE(映画館)で、取り扱い可能(入場)にするために、スタッフさん若しくは自動改札機(参照設定)に見せる又は通す(登録)することが必要です。
ちょっとくどいですね。(笑)

ともあれ、先ほどアセンブリ登録したライブラリは、VBAに参照設定することによって使うことができる、ということを覚えておいてください。
「アセンブリの参照が不足しています。」の類のエラー出力は、この辺に関係してくることが多いようです。



VBEを起動し[ツール]-[参照設定]を選択します。





ソースコードは、下記の通りです。
注意すべき点は、オブジェクトの作成時、"New"を忘れずに付け加えるところです。
必ず、"New"を付けてください。

    Sub test()
        Dim obj As New ExcelLibraryVer1.ExcelExLibrary
        Dim str As String
        obj.setName("こねこまろ")
        str = obj.getName()
        MsgBox str
    End Sub
    

下記は、実行結果です。
上記の、ソースコードを記述する時点で、ゲッター、セッターなどのメソッドについてVBEのインテリセンスが効いていれば、おそらく、成功するであろうと思われますが、
物は試しです。マクロからSubプロシージャを呼んで実行してみてください。


お疲れさまでした。
以上で終了となります。

4.補足

参照
 
PHP  |  JavaScript  |  ASP.NET  |  spira-architecture.com  |  MaterialShangri-La