Visual Studio 2019 によるExcelアドインの作成

# Visual Studio 2019 ProfessionalによるExcelアドインの作成

## 内容
Visual Studio 2019(以後「VS2019」)を使ってExcelアドインを作成できるよう環境構築を行い、基本的な実装を行います。

本手順では Professional エディションでの手順を記載しますが、Communityでも動作確認済みです。
また一部インターフェースは異なりますがVisual Studio 2017でも同じ操作で本手順を実施できることは確認済みです。

もともとはクラスライブラリ(COMオブジェクト)を実装するつもりでしたが、これまでアドインの作成を行ったことがなかった(というか避けていた)ことを思い出し、試しに作成してみることにしました。
本記事はその際に行った手順の個人的備忘録&社内展開用です。


## 概要
本記事の手順は主に以下となります。

1. Visual Studio 2019の環境設定
- アドイン用のプロジェクトの作成
- アドインにリボンを追加
- デバッグ
- Excelからイベントを受け取る
- アドインの発行
- プロジェクトのクリーンアップ

なお、本記事は以下の環境で動作を確認しています。

- Windows 10 Professional
- Visual Studio Professional 2019 (Visual Studio Community 2019 及び Professional 2017 でも確認済み)
- Excel 2013以降 (VS2017ではExcel2010向けアドインも開発可能でした)


## 【1. Visual Studio 2019の環境設定】
Visual Studioでアドイン開発を行えるように設定します。
まず、Windowsメニューから「Visual Studio Installer」を実行します。

起動したら、「変更」ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/9bd1f2a2-a8aa-3077-cc5e-daa9ae76fc95.png)


「変更」ボタンを押すと構成ダイアログが表示されるので、「個別のコンポーネント」タブを選択し、下の方に存在する「Visual Studio Tools for Office (VSTO)」をチェックします。
チェックすると自動的に依存ファイルの構成が行われるので、そのまま「変更」ボタンを押しインストールを開始します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/a93e4bd4-334c-7938-5352-80f25d6c5425.png)

インストールが完了したら、「起動」ボタンからVS2019を起動してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/c26acf74-e2df-e15f-b906-88e5900a419d.png)


## 【2. アドイン用のプロジェクトの作成】
「新しいプロジェクトの作成」を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/7bf7cd05-6039-73b1-c7ec-406cfac51617.png)

「新しいプロジェクトの作成」ダイアログが表示されます。
右上のフィルタ設定で「Office」を選択すると、Office製品の開発用テンプレートが表示されます。
下記の例では「Excel 2013 VSTOアドイン」を選択しています。
なお、対象のアプリケーションがインストールされていない場合、デバッグ操作が行なえません。
バージョンが異なる場合もデバッグが行なえませんので注意してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/279c7d76-3837-7e68-6477-aea9418ae194.png)

プロジェクト名や保存場所、フレームワークを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/54fcf586-d9c1-291e-ee70-d55c2ecb4348.png)

プロジェクトが作成されると以下のように空のプロジェクトが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/524cca4f-57a8-d580-1836-77890523d0a0.png)

## 【3. リボンを追加】
Excelのリボンにボタンを追加し、ボタンが押されたときに処理を実行するようにします。
プロジェクト右クリックから [追加] > [新しい項目] を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/db9d7a8b-1fd2-7af2-2cda-46e09b1cf21d.png)

表示されたダイアログから 「リボン(ビジュアルなデザイナー)」を選択し、[名前]指定して、[追加]ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/fbe65a84-c9e9-1dbf-872a-09e0fcb46988.png)

リボンが追加され、デザイナが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/907f5c9b-f313-a400-70ff-ffc8e483634e.png)


続いて追加されたリボンにボタンを追加します。
ツールボックスの「Office リボン コントロール」からボタンを選択し、リボンのデザイナ上に Drag & Drop します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/2db77696-9006-0939-c471-a6dbb6e9ea48.png)


デザイナ上にボタンが追加されたら、追加されたボタンをダブルクリックします。
ソースエディタが開き`private void button1_Click` メソッドが追加されるので、ここにボタンを押されたときの処理を記述します。
下記の例ではアクティブシートのA1セルの内容を書き換えるコードを書いています。

```c#:Ribbon1.cs_button1_Click
private void button1_Click(object sender, RibbonControlEventArgs e)
{
    // アクティブシート取得
    var activeSheet = Globals.ThisAddIn.Application.ActiveSheet as Microsoft.Office.Interop.Excel.Worksheet;

    // セル編集
    activeSheet.Range["A1"].Cells.Value = "button1 click";
}
```

下記のようになっていればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/fd725d20-ef4b-7740-0942-0bcf2e90aa07.png)


## 【4. デバッグ】
この状態で一度デバッグを実行してみます。
[デバッグ]メニューから [デバッグの開始] を実行するか F5 キーを押します。
アドインのビルドが走り、実行が開始されるとExcelが起動し新しいワークブックが開きます。
新しいワークブックが開かない場合、起動されたExcel上で「空白のブック」を選択してください。

開かれたExcel上で[アドイン]を選択すると、先程作成したボタンが追加されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/88d20bab-4476-9bb5-b5c1-bf40025de752.png)
ボタンを押してみると、セルA1にプログラムで指定された値が書き込まれます。

正しく動作することが確認できたら、Excelを終了します。
ワークブックを保存するか聞かれますが、保存する必要はありません。
Excelが終了するとデバッグが終了し、Visual Studioが編集状態に戻ります。



## 【5. Excelからイベントを受け取る】
アドインがExcelからイベントを受け取って、独自処理を実行するように実装します。
本例ではシートがActiveになった場合のイベント「SheetActivate」をフックします。

変更するファイルは「ThisAddIn.cs」になります。
このファイルはプロジェクト作成時に自動的に作成されています。
ここにイベント発生時の処理を実装し `ThisAddIn_Startup` メソッド内でイベントハンドラを追加します。
具体的には以下のようにソースを書き換えます。

```c#:ThisAddIn.cs_ThisAddIn_Startup(変更)
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
    this.Application.SheetActivate += Sheet_Active;
}
```

```c#:ThisAddIn.cs_Sheet_Active(追加)
// シートアクティブ時の処理
void Sheet_Active(object sh)
{
    // アクティブシート取得
    var activeSheet = (Excel.Worksheet)sh;

    // メッセージボックスでアクティブになったシート名を表示
    MessageBox.Show(activeSheet.Name, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
```

なお、MessageBoxを使うために `using System.Windows.Forms;` を追加する必要があります。

今回の変更点は以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/c49e70bc-c332-7d51-6dc7-837144a6c419.png)

変更が完了したら早速デバッグしてみましょう。
シート変更時に以下のように表示されれば成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/53477c5c-0f57-5d7c-d1e4-6b816ab7f07b.png)



## 【6. アドインの発行】
アドインを発行して別のPCに配布できるようにします。
[ビルド]メニューから「hogehogeの発行」を実行し発行先を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/bd8432ad-63c3-09e7-1c7b-c54dac71ba21.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/d4efd6de-4fa9-1636-7e61-dee55774c8fe.png)

続いて規定のインストールパスを指定するように表示されますが、基本的には「CD-ROMまたはDVD-ROMから」を選択しておけば問題ありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/872c7193-33cd-0ed3-5db5-5d153abe0037.png)

発行が完了すると、先に指定したフォルダに `setup.exe` を含む配布用のファイルが作成されます。
このフォルダに含まれるファイルを一式持っていき、 `setup.exe` を実行すると他のPCにアドインをインストールすることが可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454012/458a4c9f-4e64-c174-5a0d-101adb5b12cc.png)


なお、アンインストールするときはコントロールパネルの「プログラムと機能」から削除することが出来ます。


## 【7. プロジェクトのクリーンアップ】
すべてが完了したら、[ビルド]メニューから[ソリューションのクリーン]を実行します。
これを行うことでExcel起動時に開発中のアドインが読み込まれないようになります。
通常ソリューションのクリーン操作はビルドした成果物を削除しますが、それに加えてレジストリエントリやOfficeのセキュリティ設定を削除してくれるようです。

なお、開発が続く場合や開発中のアドインを引き続き利用する場合はこの操作は不要です。


## 最後に
以上でExcelアドインの基本的な実装ができるようになりました。
今まで避けていたのに思っていたよりも簡単でした。
ちょうどExcelからWindowsAPIを大量に叩かないといけない案件があるので、これで実装してみようかと思います。