はじめに
Excel-DNAやVBAを使用せずに、C#のみで自作のワークシート関数(ユーザー定義関数、User-defined functions、UDFs)を作成する方法です。VBAマクロで作成した関数と異なり、高速で処理をすることができます。
Excel から使うマネージDLL を作る。 | supermab's blog
作成方法
-
Visual Studio を起動します。
-
プロジェクト名として「MyAddin」を入力し、フレームワークとして「.NET Framework4.8」を選択後「作成」を押します。ここでは「MyAddin」と設定しましたが他の名前でも構いません。
-
Class1.cs
using System; using System.Runtime.InteropServices; using Microsoft.Win32; namespace MyAddin { //インターフェース [ComVisible(true)] [Guid("71E317FB-04C2-48CF-BEB4-2B4452116B7B")]//GUID(変更必要) [InterfaceType(ComInterfaceType.InterfaceIsDual)] public interface IUdfs { //公開したい関数 double nibai(double x); } //クラス [ComVisible(true)] [Guid("0679B1F1-A380-4D18-A5BB-BD5B42BF7A0B")]//GUID(変更必要) [ProgId("MyAddin.Udfs")] [ClassInterface(ClassInterfaceType.None)] public class Udfs : IUdfs { //公開したい関数の実装 public double nibai(double x) { return x * 2; } //以下おまじない //Regasmでの登録時に行われる処理 [ComRegisterFunctionAttribute] private static void RegisterFunction(Type type) { //CLSID\{GUID}\Programmable //新規作成 Registry.ClassesRoot.CreateSubKey(@"CLSID\{" + type.GUID.ToString().ToUpper() + @"}\Programmable"); //CLSID\{GUID}\InprocServer32 //既定の値を変更:mscoree.dll→C:\Windows\system32\mscoree.dll RegistryKey key = Registry.ClassesRoot.OpenSubKey(@"CLSID\{" + type.GUID.ToString().ToUpper() + @"}\InprocServer32", true); key.SetValue("", System.Environment.SystemDirectory + @"\mscoree.dll", RegistryValueKind.String); } //Regasmでの登録解除時に行われる処理 [ComUnregisterFunctionAttribute] private static void UnregisterFunction(Type type) { //CLSID\{GUID}\Programmable //削除 Registry.ClassesRoot.DeleteSubKey(@"CLSID\{" + type.GUID.ToString().ToUpper() + @"}\Programmable", false); } } }
-
ソースコード内に2箇所ある
//GUID(変更必要)
のコメント部のGUIDを新規作成したものに置き換えます。2箇所には別々のGUIDを新規に設定します。GUIDの新規作成方法
「ツール」から「GUIDの作成」を選択します。
形式を選択して「コピー」を押しクリップボードにコピーしたら「終了」を押します。
-
64bit用のExcelを対象にするので構成をx64※に変更します。「Release」を選択後、「Any CPU」をプルダウンし、「構成マネージャー」を選択します。
※32bit用のExcelを対象にする場合はx86
登録して使用する
-
管理者権限でコマンドプロンプトを開いてRegAsmを利用して登録します。
REM 以下は64bit版Excelの場合。32bitの場合はFramework64をFrameworkに変更する。 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe /tlb /codebase MyAddin.dll
-
Excelを開いて「開発」タブ→「Excelアドイン」をクリックします。アドイン画面が出るので「オートメーション」を押します。
通常の関数、例えばSUMであれば「S」を押した時点で関数候補としてSUMが出てきますが、今回の方法で作成したワークシート関数の場合は「n」を押しても「nibai」が候補として出てきませんでした。
登録を解除して使用をやめる
-
管理者権限でコマンドプロンプトを開いてRegAsmを利用して登録を解除します。
REM 以下は64bit版Excelの場合。32bitの場合はFramework64をFrameworkに変更する。 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe /tlb /u MyAddin.dll
-
Excelを開いて「開発」タブ→「Excelアドイン」をクリック。「Myaddin」のチェックを外そうとするとアドインが見つからないので削除するか聞いてくるので「はい」を押します。その後「OK」を押せば終了です。
補足
上記はVisual Studioを立ち上げて作成しましたが、コマンドラインで作成することも可能です。
キーペアの作成。Sn.exeの場所は環境によって異なるためDeveloper Command Promptを立ち上げてwhere sn
で確認します。
sn -k MyAddin.snk
コンパイル&登録(管理者権限で実行)
REM ソースファイル名はMyAddin.csとする。
REM 以下は64bit版Excelの場合。32bitの場合はFramework64をFrameworkに変更する。
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /target:library /keyfile:MyAddin.snk /platform:x64 MyAddin.cs
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe /tlb /codebase MyAddin.dll
登録解除(管理者権限で実行)
REM 以下は64bit版Excelの場合。32bitの場合はFramework64をFrameworkに変更する。
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe /tlb /u MyAddin.dll
またPowerShellを利用することでGUIDを作成しクリップボードにコピーすることができます。
(New-Guid).Guid | clip
参考URL
インターフェース
- 【C#】インターフェイスの利点が理解できない人は「インターフェイスには3つのタイプがある」ことを理解しよう - Qiita
- インターフェース - C# によるプログラミング入門 | ++C++; // 未確認飛行 C
COM
- C#でCOM In-Process Server - Qiita
- C#からのCOMの利用 - COMサーバ
- ソフトウェアを楽しく作ろう!プログラミング言語【C#】を学ぶ | C# EXCEL・DLLを作ってVBAで使う
- COM への .NET コンポーネントの公開 - .NET Framework | Microsoft Learn
- ComRegisterFunctionAttribute クラス (System.Runtime.InteropServices) | Microsoft Learn
- Registering Classes | Microsoft Learn
署名
- 方法: 公開キーと秘密キーのキー ペアを作成する | Microsoft Learn
- 方法: 厳密な名前でアセンブリに署名する | Microsoft Learn
- インサイド .NET Framework [改訂版]第2回 アセンブリのアイデンティティ(1/5) - @IT
GUID作成