Office関連

SharpDevelopでExcel用COMアドインを作成する方法

SharpDevelopのインストールと日本語化」で紹介しているSharpDevelopには、COMアドインを作るためのテンプレートが用意されているので、Officeアプリケーションで使えるCOMアドインを簡単に開発することができます。

Excel用COMアドインの作成方法

※ 下記は日本語化したSharpDevelopを元に説明しています。

  1. 管理者権限でSharpDevelopを起動します。管理者権限で起動しないと、ソリューションのビルド時に“Cannot unregister assembly”エラーが発生します。
  2. ファイルメニューの「新規作成」から「ソリューション」をクリックします。
  3. SharpDevelop_Excel_AddIn_01

  4. 新しいプロジェクトダイアログの「テンプレート」から「共有アドイン」を選択し、ソリューションの名前(今回はMySampleAddIn)を入力後「新規」ボタンをクリックします。
  5. SharpDevelop_Excel_AddIn_02

  6. プロジェクト」から「Microsoft.Office.Interop.Excel」と「System.Windows.Forms」への参照を追加します。
  7. SharpDevelop_Excel_AddIn_03

    SharpDevelop_Excel_AddIn_04

    SharpDevelop_Excel_AddIn_05

  8. Connect.cs」ファイルに下記コードを入力した後、F8キーを押して、ソリューションのビルドを実行します。
  9. namespace MySampleAddIn
    {
        using System;
        using System.Windows.Forms;
        using System.Runtime.InteropServices;
        using Extensibility;
        using Excel = Microsoft.Office.Interop.Excel;
    
        [GuidAttribute("0BD47D5A-31BF-4217-AF21-B2DD5B0255D5"), ProgId("MySampleAddIn.Connect")]
        [ComVisible(true)]
        public class Connect : Object, Extensibility.IDTExtensibility2, IRibbonExtensibility
        {
            private Excel.Application exApp;
            private Excel.Worksheet exSht;
            private Excel.Range exRng;
            
            public Connect()
            {
            }
    
            public void OnConnection(object application, ext_ConnectMode ConnectMode, object AddInInst, ref System.Array custom)
            {
                exApp = ((Excel.Application) application);
            }
            
            public void OnDisconnection(ext_DisconnectMode RemoveMode, ref System.Array custom)
            {
                if (exRng != null) {
                    Marshal.ReleaseComObject(exRng);
                    exRng = null;
                }
                if (exSht != null) {
                    Marshal.ReleaseComObject(exSht);
                    exSht = null;
                }
                if (exApp != null) {
                    Marshal.ReleaseComObject(exApp);
                    exApp = null;
                }
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
            
            public void OnAddInsUpdate(ref System.Array custom)
            {
            }
            
            public void OnStartupComplete(ref System.Array custom)
            {
            }
            
            public void OnBeginShutdown(ref System.Array custom)
            {
            }
            
            public string GetCustomUI(string RibbonID)
            {
                return @"<?xml version=""1.0"" encoding=""utf-8""?>
    <customUI xmlns=""http://schemas.microsoft.com/office/2006/01/customui"">
      <ribbon>
        <tabs>
          <tab id=""tabSample"" label=""Sample Tab"">
            <group id=""grpSample"" label=""Sample Group"">
              <button id=""btnSample"" label=""Sample Button"" size=""large"" imageMso=""HappyFace"" onAction=""btnSample_onAction"" />
            </group>
          </tab>
        </tabs>
      </ribbon>
    </customUI>";
            }
            
            public void btnSample_onAction(IRibbonControl control)
            {
                try {
                    exSht = (Excel.Worksheet)exApp.ActiveSheet;
                    exRng = (Excel.Range)exSht.Cells[1, 1];
                    exRng.Value = "呼び出し元のコントロールIDは「" + control.Id + "」です。";
                } catch (Exception) {
                    MessageBox.Show("エラーが発生しました。", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
        
        [ComImport, ComVisible(true), Guid("000C0396-0000-0000-C000-000000000046"), TypeLibType((short)0x1040)]
        public interface IRibbonExtensibility
        {
            string GetCustomUI(string RibbonID);
        }
        
        [ComImport, ComVisible(true), Guid("000C0395-0000-0000-C000-000000000046"), TypeLibType((short)0x1040)]
        public interface IRibbonControl
        {
            [DispId(1)]
            string Id{get;}
            [DispId(2)]
            object Context{get;}
            [DispId(3)]
            string Tag{get;}
        }
    }

    SharpDevelop_Excel_AddIn_06

  10. ビルドが終了し、DLLファイルが作成されれば作業終了です。
  11. SharpDevelop_Excel_AddIn_07

DLLファイルの作成が終了したら、今度はRegAsm.exe(アセンブリ登録ツール)を使ってDLLを登録する必要があります。

DLLファイルの登録

  1. 管理者権限でコマンドプロンプトを実行します。
  2. SharpDevelop_Excel_AddIn_08

  3. 下記コマンドを実行して「RegAsm.exe」ファイルがあるフォルダに移動します。RegAsm.exeファイルがあるフォルダは、環境によって異なる場合があります。
  4. cd "C:\Windows\Microsoft.NET\Framework\v4.0.30319"

    SharpDevelop_Excel_AddIn_09

  5. RegAsm “(SharpDevelopで作成したDLLファイルのパス)” /tlb /codebase」コマンドを実行して、DLLファイルの登録を行います。
  6. RegAsm "C:\SharpDevelop Projects\MySampleAddIn\MySampleAddIn\bin\Debug\MySampleAddIn.dll" /tlb /codebase

    SharpDevelop_Excel_AddIn_10

RegAsm.exeによるDLLファイルの登録が終了したら、今度はExcelからアドインとして使えるよう、レジストリを変更する必要があります。

アドインとして登録(レジストリ編集)

  1. レジストリエディタを起動します。
  2. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\Excel\Addins」以下に「MySampleAddIn.Connect」キーを新規追加します。
  3. 2.で追加した「MySampleAddIn.Connect」キーに下記エントリを追加します。
  4. Description(REG_SZ):COMアドインの説明。今回は「SharpDevelopで作ったサンプルアドインです。
    FriendlyName(REG_SZ):COMアドインの表示名。今回は「My Sample AddIn
    LoadBehavior(REG_DWORD):COMアドインの読み込み方法。今回は「3」(スタート時に読み込む)

    SharpDevelop_Excel_AddIn_11

以上で作業は終了です。
上記作業後Excelを起動すると、作成したアドインが読み込まれ、「Sample Tab」にある「Sample Button」も動作することが確認できます。

SharpDevelop_Excel_AddIn_12

SharpDevelop_Excel_AddIn_13

アドインの登録解除方法

アドインの登録を解除する場合は、下記のような作業を行う必要があります。

  1. レジストリエディタを起動し、アドイン登録時に追加したキー(上記手順の場合は「HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\Excel\Addins\MySampleAddIn.Connect」キー)を削除します。
  2. 管理者権限でコマンドプロンプトを起動します。
  3. RegAsm.exe」ファイルがあるフォルダに移動します。
  4. /u」オプションを付けてRegAsm.exeを実行し、DLLファイルの登録を解除します。
  5. RegAsm "C:\SharpDevelop Projects\MySampleAddIn\MySampleAddIn\bin\Debug\MySampleAddIn.dll" /tlb /u

    SharpDevelop_Excel_AddIn_14

参考Webページ

おわりに

というわけで、SharpDevelopを使ってCOMアドインを作成してみました。
リボンUIの実装に若干手間取りましたが、参考Webページのおかげで何とか解決できました(動作確認だけしたかったので、インターフェースはかなり適当です)。

.NETからのExcel云々という話は、昔、COM参照の解放し忘れでプロセスが残り続ける問題で苦労した覚えがあるのですが、共有アドインの場合はどうなんでしょう…?一応OnDisconnectionにReleaseComObjectを入れましたが、このあたりの“お作法”についてはどうするのが一番良いのかイマイチ分かりません(^^;

また、RegAsmでDLLを登録したり解除したり、という作業は結構面倒くさいです。
4年ほど前にこの作業を簡略化するためのスクリプトを書いたことがあるので、興味がある方は下記記事もご覧ください。

・ドラッグされたマネージドDLLをRegAsmで登録するスクリプト
https://kinuasa.wordpress.com/2011/04/07/%E3%83%89%E3%83%A9%E3%83%83%E3%82%B0%E3%81%95%E3%82%8C%E3%81%9F%E3%83%9E%E3%83%8D%E3%83%BC%E3%82%B8%E3%83%89dll%E3%82%92regasm%E3%81%A7%E7%99%BB%E9%8C%B2%E3%81%99%E3%82%8B%E3%82%B9%E3%82%AF%E3%83%AA/

関連記事

  1. Office関連

    [Excel]別インスタンスからの貼り付け時のダイアログを非表示にする方法

    Msdn フォーラムに「excel 2010 貼り付けで警告メッセージ…

  2. Office アドイン

    PowerPoint用のOffice用アプリ

    当ブログでも散々紹介しているOffice用アプリ(apps for O…

  3. Office関連

    「2014年12月のWindows Update以降コマンドボタンが使えなくなった」トラブルへのFi…

    当ブログでも「KB2553154の更新プログラムをアンインストールする…

  4. Office関連

    Excelを別インスタンスで起動する方法

    「Excel 別インスタンス 起動」といったキーワード検索でのアクセス…

  5. Office関連

    PowerShellからNetOfficeを使ってWordやPowerPointを操作する方法

    前回の記事関連で、WordやPowerPointもドンとこいで…

コメント

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

Time limit is exhausted. Please reload CAPTCHA.

最近の記事

アーカイブ

RapidSSL_SEAL-90x50
PAGE TOP