朝会発表テーマ

VBAからC#の関数を呼び出す

1.行いたいこと

・通常Officeソフト(AccessやExcel)ではVBAという言語を使いプログラミングを行う。
・一方でVisual StudioというソフトではC#で開発を行う。C#は文法やライブラリの面から、VBAと比べて開発しやすい。
→C#で作成した関数をVBAから呼び出せないか?

2.周辺技術

・Office系のソフトで機能拡張を行う際に使用する「参照ライブラリ」はCOM形式のdllファイルとなっている。
・つまり、C#で作成する関数をCOM形式のdllとして開発すれば、Officeソフトからも使用可能となる。

3.手順概要

(1)Visual Studioで「クラスライブラリ」テンプレートを使いプロジェクトを作成。
 ・クラスライブラリがCOM形式をなるようにプロジェクト設定とコーディングを一部変更。
 ・作成成果物はCOM形式のDLL(.dll)となる。
(2)regasmコマンドを用いて、作成したDLLをWindowsに登録、タイプライブラリファイル(.tlb)を生成。
 ・regasmコマンドは.NET Frameworkに含まれている。
 ・(2)の操作により、作成したDLLファイルはOfficeソフトの参照ライブラリとして選択可能になる。
(3)Officeソフトの参照設定画面で、(2)で作成したタイプライブラリファイルを選択して保存。
 ・(1)~(3)の操作によりVBAのコード内でC#の関数を記述することが可能となる。

4.調査結果・課題点

・C#で作成したDLLをAccess・ExcelのVBAから呼び出すことに成功した。
・作成したDLLを、別のPCで使用すると実行時エラーが発生する(原因不明)。

参考
「C# で COM オブジェクトを作ってみる」
[http://qiita.com/tomochan154/items/1ce33f2aef167c0fed9d]
「C#でVBA向けの.NETライブラリ(COMコンポーネント)を作成するには?[C#]」
[http://www.atmarkit.co.jp/fdotnet/dotnettips/1064combycs/combycs.html]
「VBAから扱えるDLLをC#で書いてみる。」
[https://www.ka-net.org/blog/?p=5464]

補足資料

C#側ソースコード

using System.Runtime.InteropServices;

namespace ClassLibraryForVBA
{
    [Guid(m_GUID)]
    public class LibFunc
    {
        //COM用に公開するGUID値
        public const string m_GUID = "1DB3978A-0414-4E14-B44C-8E30A365F929";

        //VBAから利用するメソッド
        public void TestFunc(int param1, int param2)
        {
            //2つの引数の値をメッセージボックスに表示する
            string msg = "渡された引数は「" + param1 + "」と「" + param2 + "」です";
            System.Windows.Forms.MessageBox.Show(msg);
        }
    }
}

VBA側ソースコード

Option Compare Database
'フォーム画面のボタンを押した時の処理
Private Sub B_01_Click()
    '作成したCOMオブジェクトを取得
    Dim dotnetObj As New LibraryForVBA.LibFunc
    
    'C#の関数呼び出し
    Call dotnetObj.TestFunc(3, 7)
End Sub

上記サンプルプログラムを実行させた様子
・「渡された引数は~」と表示されているメッセージボックスはC#側のプログラムによるもの。
→VBAからC#の関数が呼び出されていることがわかる。

PG作成手順(C#)

C#側プログラム作成手順 [Microsoft Visual Studio Community 2015にて動作確認]

1.新しいプロジェクトで、テンプレート「Visual C#」内の「クラスライブラリ」を選択

2.プロジェクト設定を変更する。
・「アプリケーション」→「アセンブリ情報」→「アセンブリをCOM参照可能にする」チェックオン
・「ビルド」→「アセンブリ情報」→「アセンブリをCOM参照可能にする」チェックオン

3.ソースプログラムを作成
・COM形式のライブラリのため、GuidAttributeをセット。
・GUIDの値は適当で良い(Visual Studioの場合、「ツール」→「GUIDの作成」が利用できる)。

4.作成したDLLファイルをPCに登録する。
・作成したDLLを適当なフォルダに配置
・regasmコマンド(*)を使って、次のコマンドを発行。
cd “(DLLを配置したフォルダ)”
regasm LibraryForVBA.dll /tlb:LibraryForVBA.tlb /codebase

※解除する場合は、regasm /u LibraryForVBA.dll

(*)
Visual Studioをインストールしている場合「開発者コマンドプロンプト」から実行可能。
通常のPCでは.NET Frameworkフォルダ内にコマンドがある。
いずれの場合も、管理者権限は必須。

以上。

PG作成手順(VBA側)

VBA側プログラム作成手順 [Access 2016にて動作確認]

1.作成したDLLを参照設定する
・VBAのエディタ(ここではAccess)の参照設定画面を開き、参照ボタンから、regasmコマンドにより作成したDLLのタイプライブラリを選択、OKボタンで確定する。

2.C#の関数を呼び出すプログラムを作成
・ここでは、フォーム画面を1つ作成。フォーム画面のボタン押下時にC#の関数呼び出しを行う。

3.実行結果

以上。

コメント