くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

初心者がVBAマクロをExcelアドインにしてみた

前の記事で、はじめてExcel AddInをつくってみたときの備忘録。

wannabe-jellyfish.hatenablog.com

次にアドインを作る予定もないので、きっと忘れる自分のために。。。

全体の流れというか構成というか

全体の流れというか雰囲気とか構成とかやることはこんな感じ。

  1. メニュー等のUIを変更する
  2. 変更したUIのイベントで実行する本体を開発
  3. アドインを追加した際に、UIが変更されるようにする

基本的に動かしながらなので、

  1. 空のxlsmファイルを作って
  2. xlsmファイル上で、開発・確認
  3. 完成したら、xlamで書き出し

という感じでつくった。

1. メニュー等のUIを変更する

右クリックしたときに出るメニュー(コンテキストメニュー)に表示するときはこんな感じ。

'**********************************************************************************
'* Setup Menu
'**********************************************************************************
Sub SetupMenu()
    Dim menuControls As CommandBarControls
    Dim menuGroup As CommandBarControl
    
    'セルを選択したときのCommandBarControlsを取得
    Set menuControls = Application.CommandBars("Cell").Controls

    'menuControlsに「My Menu Group」というグループを追加。
    Set menuGroup = menuControls.Add(Type:=msoControlPopup)
    menuGroup.Caption = "My Menu Group"
    
    
    '作ったグループに「My Menu Button」というボタンを追加。
    'ボタンが押されると「ExecuteActionName」サブルーチンを実行
    With menuGroup.Controls.Add(Type:=msoControlButton)
         .Caption = "My Menu Button"
         .OnAction = "ExecuteActionName"
End Sub

削除するときは、こんな感じ。

'**********************************************************************************
'* Delete Menu
'**********************************************************************************
Sub DeleteMenu()
    '独自に追加したメニューを全削除。デバックとか開発中はこっち。
    Application.CommandBars("Cell").Reset

    '指定したメニューだけを削除。アンインストールのときはこっち。
    Application.CommandBars("Cell").Controls("My Menu Group").Delete
End Sub

2. 変更したUIのイベントで実行する本体を開発

ここについてはいわずもがなという感じなので、思いのまま作る。

'**********************************************************************************
'* ExecuteActionName
'**********************************************************************************
Sub ExecuteActionName()
    '思いのままに
    MsgBox "思いのままに"
End Sub

3. アドインを追加した際に、UIが変更されるようにする

1.で用意したSetupMenuDeleteMenuは、アドインをインストール/アンインストールしたときに実行してほしい。

そういった処理は、標準モジュールではなく、ThisWorkBookの方に書く。

f:id:wannabe-jellyfish:20170603191749p:plain

'**********************************************************************************
'*インストール時の処理
'**********************************************************************************
Private Sub Workbook_AddinInstall()
    Dim menuControls As CommandBarControls
    Dim menuGroup As CommandBarControl
    
    'セルを選択したときのCommandBarControlsを取得
    Set menuControls = Application.CommandBars("Cell").Controls

    'menuControlsに「My Menu Group」というグループを追加。
    Set menuGroup = menuControls.Add(Type:=msoControlPopup)
    menuGroup.Caption = "My Menu Group"
    
    
    '作ったグループに「My Menu Button」というボタンを追加。
    'ボタンが押されると「ExecuteActionName」サブルーチンを実行
    With menuGroup.Controls.Add(Type:=msoControlButton)
         .Caption = "My Menu Button"
         .OnAction = "ExecuteActionName"
End Sub


'**********************************************************************************
'* アンインストール時の処理
'**********************************************************************************
Private Sub Workbook_AddinUninstall()
    '指定したメニューだけを削除。アンインストールのときはこっち。
    Application.CommandBars("Cell").Controls("My Menu Group").Delete
End Sub

実際は1.で作った、SetupMenuDeleteMenuを呼ぶ感じ。

番外:アドインをインストールするVB Script

今回作ったアドインはインストールするのが手間で、わかっている人でないと難しい。。
ので、インストールするスクリプトなどを用意するとらくちん。

fuku2014さんのQiita記事を参考に作ってみた。

'インストールするスクリプト
Const ADDIN_NAME="MyAddIn"

Dim objExcel, objFileSys, strAdPath, strMyPath, strAdCp, strMyCp

Set objExcel   = CreateObject("Excel.Application")
Set objFileSys = CreateObject("Scripting.FileSystemObject")

'Set install path for Add-In
strAdPath = objExcel.Application.UserLibraryPath
strAdCp   = objFileSys.BuildPath(strAdPath, ADDIN_NAME & ".xlam")

'Set target Add-In location path
strMyPath = Replace(WScript.ScriptFullName, WScript.ScriptName, "")
strMyCp   = objFileSys.BuildPath(strMyPath, ADDIN_NAME & ".xlam")

'Copy target Add-In
objFileSys.CopyFile strMyCp, strAdCp

'Set enable target Add-In for Excel
objExcel.Workbooks.Add
With objExcel.AddIns.Add(strAdCp,True)
             .Installed = True
End With
objExcel.Quit

Set objExcel   = Nothing
Set objFileSys = Nothing

MsgBox "Install is Complete!"
'アンインストールするスクリプト
Const ADDIN_NAME="MyAddIn"

Dim objExcel, objFileSys, strAdPath, strMyPath, strAdCp, strMyCp

Set objExcel   = CreateObject("Excel.Application")
Set objFileSys = CreateObject("Scripting.FileSystemObject")

'Set install path for Add-In
strAdPath = objExcel.Application.UserLibraryPath
strAdCp   = objFileSys.BuildPath(strAdPath, ADDIN_NAME & ".xlam")

'Set disable target Add-In for Excel
objExcel.Workbooks.Add
With objExcel.AddIns(ADDIN_NAME)
             .Installed = False
End With
objExcel.Quit

'Delete Add-In in intall path
objFileSys.DeleteFile strAdCp

Set objExcel   = Nothing
Set objFileSys = Nothing

MsgBox "Uninstall is Complete!"

こんな感じで作ったアドインは、GitHubで公開しているので、
細かいところがわからなければ、こちらも合わせて読みながら。

github.com

以上!!

参考にしたサイト様