ロゴ(青) Excel/VBA Tips ロゴ(緑)

Tips27: Excel2013/2016 アドインブックによるCommandBar メニューとアドインタブ

        ( 2016/12/6 : 初版 , 2018/5/8 : 8 節を追記 )

Excel 2013 / 2016 の SDI ( Single Documents Interface ) 環境で、アドインブック が作成する CommandBar メニュー ( 「アドイン」 タブ に
収容されます) を トラブル なく運用するための手順書です。 特に 「保存タイプの メニュー ( Temporay:=False ) 」 の場合、アドイン登録/
解除の実行手順によっては、期待通りに反映されないトラブルを引き起こしますので注意が必要です。

[ Temporary := False or True ] タイプの 区別は、アドイン登録時にアドインタブが直ぐに出るか否かで判ります ( §5 / §6 参照)。

1.  CommandBar メニュー と リボン
2.  アドインブックにおける CommandBar メニューの作成方式
3.  MDI と SDI
4.  検証 マクロ
5.  [ Temporary := True ] メニュー と [ アドイン登録/解除 ] 手順
6.  [ Temporary := False ] メニュー と [ アドイン登録/解除 ] 手順
    6-1.  アドインメニューが期待通りに 作成/削除 される 正しい手順
    6-2.  アドインメニューが期待通りに 作成/削除 されない 誤った手順
7.  バグか?  仕様か?
8.  [ Temporary:=True ] メニューに 『一時的 アドイン 解除処理』 が及ぼす影響   ( 2018/5/8 追記 )

CommandBar メニュー から 『 リボン UI 』 への 移行 を 検討してみようという方は、下記記事を参考にしてください。
      [ Tips23: CommandBar から リボンUI へ ]    http://addinbox.sakura.ne.jp/Excel_Tips23.htm


[ この場所への リンク ]   

1.CommandBar メニュー と リボン

CommandBar によるメニューはExcel2003以前で使われていた機能です。

  Excel2007以降では、CommandBar で作成されたメニューは
  「アドイン」タブ内に表示されます
  (アドインではない「通常ブック」で作成する CommandBar
  メニューも「アドイン」タブに収容されます)


なお、CommandBars("WorkSheet Menu Bar") 上に追加されたメニューでは、リボン(アドインタブ)表示に
関して、下記の一時的な表示不具合があります。

            [ KB2648925 ]  https://support.microsoft.com/ja-jp/kb/2648925 
                グラフ オブジェクトが アクティブな状態でリボンの [アドイン] タブを選択すると、
                [アドイン]-[メニュー コマンド] 上のコマンドが表示されなくなる場合があります。
 
 グラフオブジェクトがアクティブ(選択状態)になっている間、一時的にメニューが非表示になります
 シート等の他をアクティブにすれば再び表示されます。この時、アドインタブ内に当該メニューしか登録
 されていない場合には、アドインタブ自体も一時的に消えます。「表示が一時的に消える」だけで、メニュー
 そのものが削除される訳ではありません。

            "WorkSheet Menu Bar"上ではなく、「ツール」 等の メニュー 配下 として作成すれば、この不具合を回避できます。


[ この場所への リンク ]   

( この節は読み飛ばして $5 へ進んでも構いません )
2. アドインブックにおける CommandBar メニューの 作成方式

( 1 ) [ Temporary := True ] タイプ
    Workbook_Open にマクロを記述することにより、エクセル起動時に【毎回】作成します。
    このメニューはエクセル終了時に自動的に削除されます。

    「エクセル終了時に自動削除」なので、アドイン解除を行なっても、そのエクセル プロセス中はメニューが残ります
    その為、Workbook_AddinUninstall もしくは Workbook_BeforeClose での削除処理が必要です。

      (注) CommandBar メニューでは、「同一名」 での 重複作成 が出来てしまいますので、事前に 「作成する メニュー名の存在確認」
            を行なうべきです (下記マクロでは 「存在確認」 の部分は省略しています)。
   --- ThisWorkbook モジュール ---

 Private Sub Workbook_Open()
   Dim MyCB As CommandBar
   Dim MyCBTool As CommandBarControl
   Dim MyCBMenu As CommandBarControl

   On Error Resume Next

   Set MyCB = Application.CommandBars("WorkSheet Menu Bar")
   Set MyCBMenu = MyCB.Controls.Add(Type:=msoControlPopup, Temporary:=True)
   MyCBMenu.Caption = "メニュー1"

   Set MyCBTool = MyCB.FindControl(ID:=30007)    '[ツール(&T)]  ID=30007
   Set MyCBMenu = MyCBTool.Controls.Add(Type:=msoControlPopup, Temporary:=True)
   MyCBMenu.Caption = "メニュー2"
 End Sub


 Private Sub Workbook_AddinUninstall()
 ' or Private Sub Workbook_BeforeClose(Cancel As Boolean)
   Dim MyCB As CommandBar
   Dim MyCBTool As CommandBarControl

   On Error Resume Next

   Set MyCB = Application.CommandBars("WorkSheet Menu Bar")
   MyCB.Controls("メニュー1").Delete

   Set MyCBTool = MyCB.FindControl(ID:=30007)    '[ツール(&T)]  ID=30007
   MyCBTool.Controls("メニュー2").Delete
 End Sub


( 2 ) [ Temporary := False ] タイプ
    このメニューは自動的には削除されません。
    Workbook_AddinInstall で作成し、Workbook_AddinUninstall で削除します。
    即ち、アドイン登録 / アドイン解除(アドインダイアログでチェックを入れる/外す)の際にのみ実行します。

    このメニューは 常設メニュー として下記の エクセル環境設定ファイルに記録されます
      C:\Users\ユーザーアカウント\AppData\Roaming\Microsoft\Excel\Excel15.xlb (Windows10の場合)
          補:Excel2013/2016/2019 ⇒ Excel15.xlb  ,  Excel2010 ⇒ Excel14.xlb
              Excel2007 ⇒ Excel12.xlb  ,  Excel2003 ⇒ Excel11.xlb


      (注) CommandBar メニューでは、「同一名」 での 重複作成 が出来てしまいますので、事前に 「作成する メニュー名の存在確認」
            を行なうべきです (下記マクロでは 「存在確認」 の部分は省略しています)。
   --- ThisWorkbook モジュール ---

 Private Sub Workbook_AddinInstall()
   Dim MyCB As CommandBar
   Dim MyCBTool As CommandBarControl
   Dim MyCBMenu As CommandBarControl

   On Error Resume Next

   Set MyCB = Application.CommandBars("WorkSheet Menu Bar")
   Set MyCBMenu = MyCB.Controls.Add(Type:=msoControlPopup, Temporary:=False)
   MyCBMenu.Caption = "メニュー3"

   Set MyCBTool = MyCB.FindControl(ID:=30007)    '[ツール(&T)]  ID=30007
   Set MyCBMenu = MyCBTool.Controls.Add(Type:=msoControlPopup, Temporary:=False)
   MyCBMenu.Caption = "メニュー4"
 End Sub


 Private Sub Workbook_AddinUninstall()
   Dim MyCB As CommandBar
   Dim MyCBTool As CommandBarControl

   On Error Resume Next

   Set MyCB = Application.CommandBars("WorkSheet Menu Bar")
   MyCB.Controls("メニュー3").Delete

   Set MyCBTool = MyCB.FindControl(ID:=30007)    '[ツール(&T)]  ID=30007
   MyCBTool.Controls("メニュー4").Delete
 End Sub



[ この場所への リンク ]   

( この節は読み飛ばして $5 へ進んでも構いません )
3.MDI と SDI

( 1 )  Excel2007/2010 のウィンドウは MDI ( Multi Documents Interface ) です。

    エクセル本体のウィンドウ内に、個々のワークブックのサブウィンドウが存在し、リボンはエクセル本体の
    ウィンドウに配置されています。その為、複数のワークブックを開いても、また、エクセルを再起動しても、
    常に「アドイン」タブからメニューを利用できます。

( 2 )  Excel2013からウィンドウが SDI ( Single Documents Interface ) に変わりました。

    個々のワークブックが独立したウィンドウとして存在しており、各々のウィンドウで別個にリボンが配置され
    ています。その為、複数のワークブックを開いたり、エクセルを再起動した際に、個々のワークブックウィン
    ドウに 「アドイン」 タブ が表示されない場合があります。

( 3 )  SDI ( Excel2013 以降 ) に伴う「アドイン」タブの有無について

  ( a ) 通常ブックのマクロで作成した CommandBar メニューは、そのブックのウィンドウでのみ有効です。
        そのブックのウィンドウには「アドイン」タブでメニューが表示されますが、別のブックのウィンドウに
        切り替えるとメニューは表示されません(他の有効なCommandBarメニューが無ければ、アドインタブ
        自体も表示されません)。

  ( b ) アドインブックのマクロで作成した CommandBarメニューは、全てのブックのウィンドウで有効です
        (作成方法は前述の通り)。 ただし、アドイン登録の実行手順によっては、アドインタブが表示され
        ないケースがあり、これが 『 SDI での CommandBar メニューの問題点』 になっています。


[ この場所への リンク ]   

( この節は読み飛ばして $5 へ進んでも構いません )
4.検証マクロ
    SDI_AddinTab_Test.zip ( 53 kb )
      +-- MenuTestOpen.xlam
      +-- MenuTestAddinInst.xlam
      +-- MenuTestCheckDelete.xlsm

( 1 ) MenuTestOpen.xlam
      [ Temporary:=True ] タイプの CommandBar メニューを作成するアドインです。

      Workbook_Open で作成し、Workbook_BeforeClose で削除します。
      ・ WkshOpenTempT : "WorkSheet Menu Bar" 内に作成するメニュー
      ・ ToolOpenTempT : 「ツール」メニュー配下に作成するメニュー

      メニュー状態を確認するマクロ [ MenuCheck4Open ] が付属しています。

( 2 ) MenuTestAddinInst.xlam
      [ Temporary:=False ] タイプの CommandBar メニューを作成するアドインです。

      Workbook_AddinInstall で作成し、Workbook_AddinUninstall で削除します。
      ・ WkshAddinTempF : "WorkSheet Menu Bar" 内に作成するメニュー
      ・ ToolAddinTempF : 「ツール」メニュー配下に作成するメニュー

      メニュー状態を確認するマクロ [ MenuCheck4AddinInst ] が付属しています。

( 3 ) MenuTestCheckDelete.xlsm
    ( 1 ) ( 2 ) 両方のメニュー状態を確認するマクロです。


[ この場所への リンク ]   

5.[ Temporary:=True ] メニューと [ アドイン登録/解除] 手順
    (この節はExcel2013以降を対象にしています)
      [ Temporary := False or True ] タイプの 区別は、アドイン登録時にアドインタブが直ぐに出るか否かで判ります ( §5 / §6 参照)。

このタイプのアドインメニューは、アドインブックにて『起動の度に新規作成される』ことにより、
メニューが表示されています。

アドインはエクセル起動時に通常ブックに先立ってオープンされますので、そのメニューもまた、
通常ブックがオープンされる前に作成されます。そして、その後でオープンされる全てのブック
に対してメニューが有効になっています。

なお、このタイプのアドインメニューは、アドイン登録/解除を行なったExcelプロセス中では、即座
には リボンに反映されません


このタイプのアドインメニューは、エクセルを再起動すれば 全てのワークブックウィンドウに
必ず反映されます。
   ( マクロの内容によっては例外が有り得ます )

※ kt電話郵便アドイン のメニューは、このタイプです ( xla 版 )。
※ kt関数アドインのメニューは Ver 5.00 から、このタイプになりました ( xla 版 )。 


-- [ Temporary := True ] アドイン登録/解除後に【即】再起動する場合 --
( 1 ) エクセル を 起動 ( Book1 を オープン )  
( 2 ) Book1 でアドイン登録 メニューが表示されない
( 3 ) Book1 でエクセル終了  
( 4 ) エクセルを再起動 ( Book1 を オープン ) メニュー有り
( 5 ) Book2 を追加オープン メニュー有り

( 6 ) エクセルを起動 ( Book1 を オープン ) メニュー有り
( 7 ) Book1 でアドイン解除 メニューは残っている
( 8 ) Book1 でエクセル終了  
( 9 ) エクセルを再起動 ( Book1 を オープン ) メニュー無し


-- [ Temporary := True ] アドイン登録/解除後に、直ぐには再起動しない場合 --
( 1 ) エクセル を 起動 ( Book1 を オープン )  
( 2 ) Book1 でアドイン登録 メニューが表示されない
( 3 ) Book2 を追加オープン Book2 も メニュー無し
( 4 ) Book1 / Book2 をクローズ ( 空のエクセルウィンドウ ) メニューが表示されます
( 5 ) Book3 を追加オープン メニュー有り
( 6 ) Book3 でエクセル終了  
( 7 ) エクセルを再起動 ( Book1 を オープン ) メニュー有り
( 8 ) Book2 を追加オープン メニュー有り

( 9 ) エクセルを起動 ( Book1 を オープン ) メニュー有り
( 10 ) Book1 でアドイン解除 メニューは残っている
( 11 ) Book2 を追加オープン Book2 でも メニューは残っている
( 12 ) Book1 / Book2 をクローズ ( 空のエクセルウィンドウ ) メニューは残っている
( 13 ) Book3 を追加オープン Book3 でも メニューは残っている
( 14 ) Book3 でエクセル終了  
( 15 ) エクセルを再起動 ( Book1 を オープン ) メニュー無し


[ この場所への リンク ]   

6.[ Temporary:=False ] メニューと [ アドイン登録/解除] 手順
    (この節はExcel2013以降を対象にしています)
      [ Temporary := False or True ] タイプの 区別は、アドイン登録時にアドインタブが直ぐに出るか否かで判ります ( §5 / §6 参照)。

このタイプのアドインメニューは、エクセル環境設定ファイル(Excel15.xlbに記録されることにより、
次回以降のエクセル起動時にもメニューが表示されるようになります。

ただし、このタイプでは、アドイン登録/アドイン解除を行う際の操作手順によっては Excel15.xlb に
メニュー情報が記録されず
、期待通りの結果(次回起動以降もメニュー表示 / 消去)にならない場合
があります。
    (補) 以下の検証において、Excel15.xlb の更新有無については、
          実際にエディターにて「書き込み有無」を確認しました。

※ kt関数アドイン のメニューは Ver 4.00 までが、このタイプです。

[ この場所への リンク ]   
【 [ Temporary := False ] アドイン登録 : アドインメニュー が期待通りに表示される手順 】
-- 登録 Case 1 ( 登録で期待通りに表示されるのは、この手順のみです ) --
( 1 ) エクセル を 起動 ( Book1 を オープン )  
( 2 ) Book1 でアドイン登録 メニューが表示されます
( 3 ) Book2 を追加オープン ( 必須 ) Book2 もメニュー有り
( 4 ) アドイン登録時の Book1 を先にクローズ ( 必須 )  
( 5 ) メニュー表示有りの Book2 でエクセル終了 ( 必須 ) Excel15.xlb にメニュー情報が追加される
( 6 ) エクセルを再起動 ( Book1 を オープン ) メニュー有り
( 7 ) Book2 を追加オープン メニュー有り
( 8 ) Book1 / Book2 をクローズ ( 空のエクセルウィンドウ ) メニュー有り


【 [ Temporary := False ] アドイン解除 : アドインメニューが期待通りに削除される手順 】
-- 解除 Case 1 --
( 1 ) エクセル を 起動 ( Book1 を オープン ) メニュー有り
( 2 ) Book1 でアドイン解除 メニューが消えます
( 3 ) Book1 でエクセル終了 Excel15.xlb からメニュー情報が削除される
( 4 ) エクセルを再起動 ( Book1 を オープン ) メニュー無し
 
-- 解除 Case 2 --
( 1 ) エクセル を 起動 ( Book1 を オープン ) メニュー有り
( 2 ) Book1 でアドイン解除 メニューが消えます
( 3 ) Book2 を追加オープン Book2 もメニュー無し
( 4 ) Book1 をクローズ  
( 5 ) Book2 でエクセル終了 Excel15.xlb からメニュー情報が削除される
( 6 ) エクセルを再起動 ( Book1 を オープン ) メニュー無し
 
-- 解除 Case 3 --
( 1 ) エクセル を 起動 ( Book1 を オープン ) メニュー有り
( 2 ) Book2 を追加オープン メニュー有り
( 3 ) Book2 でアドイン解除 Book2 のメニューが消えます
/ Book1ではメニューが残っている
( 4 ) メニューが表示されている Book1 を先にクローズ  
( 5 ) Book2 でエクセル終了 Excel15.xlb からメニュー情報が削除される
( 6 ) エクセルを再起動 ( Book1 を オープン ) メニュー無し

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[ この場所への リンク ]   
【 [ Temporary := False ] アドイン登録 : アドインメニューが期待通りに表示されない手順 】
-- 登録 Case 2 --
( 1 ) エクセル を 起動 ( Book1 を オープン )  
( 2 ) Book1 でアドイン登録 メニューが表示されます
( 3 ) Book1 でエクセル終了 Excel15.xlb にメニュー情報が追加されない
( 4 ) エクセル再起動 ( Book1 をオープン ) メニュー無し
 
-- 登録 Case 3 --
( 1 ) エクセル を 起動 ( Book1 を オープン )  
( 2 ) Book1 でアドイン登録 メニューが表示されます
( 3 ) Book2 を追加オープン Book2 もメニュー有り
( 4 ) Book2 をクローズ Book1 にメニュー有り
( 5 ) Book1 でエクセル終了 Excel15.xlb にメニュー情報が追加されない
( 6 ) エクセル を 再起動 ( Book1 をオープン ) メニュー無し
 
-- 登録 Case 4 --
( 1 ) エクセル を 起動 ( Book1 を オープン )  
( 2 ) Book1 でアドイン登録 メニューが表示されます
( 3 ) Book1 をクローズ (空のエクセルウィンドウ) メニューが消えます
( 4 ) Book2 を追加オープン Book2 でもメニュー無し
( 5 ) Book2 でエクセル終了 Excel15.xlb にメニュー情報が追加されない
( 6 ) エクセル を 再起動 ( Book1 をオープン ) メニュー無し
 
-- 登録 Case 5 --
( 1 ) エクセル を 起動 ( Book1 を オープン )  
( 2 ) Book1 でアドイン登録 メニューが表示されます
( 3 ) Book2 を追加オープン Book2 もメニュー有り
( 4 ) Book1 をクローズ Book2 のメニューは残っている
( 5 ) Book2 をクローズ (空のエクセルウィンドウ) メニューが消えます
( 6 ) Book3 を追加オープン Book3 でもメニュー無し
( 7 ) Book3でエクセル終了 Excel15.xlb にメニュー情報が追加されない
( 8 ) エクセル を 再起動 ( Book1 をオープン ) メニュー無し
 
-- 登録 Case 6 --
( 1 ) エクセル を 起動 ( Book1 を オープン )  
( 2 ) Book2 を追加オープン  
( 3 ) Book2 でアドイン登録 Book2 でメニューが表示されます
/ Book1 はメニュー無し
( 4 ) Book1 をクローズ Book2 はメニュー有り
( 5 ) Book2でエクセル終了 Excel15.xlb にメニュー情報が追加されない
( 6 ) エクセル を 再起動 ( Book1 をオープン ) メニュー無し
 
-- 登録 Case 7 --
( 1 ) エクセル を 起動 ( Book1 を オープン )  
( 2 ) Book2 を追加オープン  
( 3 ) Book2 でアドイン登録 Book2 でメニューが表示されます
/ Book1 はメニュー無し
( 4 ) Book2 をクローズ Book1 はメニュー無し
( 5 ) Book1でエクセル終了 Excel15.xlb にメニュー情報が追加されない
( 6 ) エクセル を 再起動 ( Book1 をオープン ) メニュー無し
 
-- 登録 Case 8 --
( 1 ) エクセル を 起動 ( Book1 を オープン )  
( 2 ) Book2 を追加オープン  
( 3 ) Book2 でアドイン登録 Book2 でメニューが表示されます
/ Book1 はメニュー無し
( 4 ) Book3 を追加オープン Book2 & Book3 はメニュー有り
/ Book1 はメニュー無し
( 5 ) Book2 をクローズ Book3 はメニュー有り
/ Book1 はメニュー無し
( 6 ) Book1 / Book3 一括クローズでエクセル終了 Excel15.xlb にメニュー情報が追加されない
( 7 ) エクセル を 再起動 ( Book1 をオープン ) メニュー無し
 
尚、Book3 を最後まで残すと メニュー が記録されます ( 登録 : Case 1 と同じ状態です )
( 5 ) Book2 をクローズ Book3 はメニュー有り / Book1 はメニュー無し
( 6-1 ) Book1 をクローズ Book3 はメニュー有り
( 6-2 ) Book3 でエクセル終了 Excel15.xlb にメニュー情報が追加される
( 7 ) エクセル再起動 ( Book1 をオープン ) メニュー有り


【 [ Temporary := False ] アドイン解除 : アドインメニューが期待通りに削除されない手順 】
-- 解除 Case 4 --
( 1 ) エクセル を 起動 ( Book1 を オープン ) メニュー有り
( 2 ) Book2 を追加オープン メニュー有り
( 3 ) Book2 でアドイン解除 Book2 のメニューが消えます/
Book1 ではメニューが残っている
( 4 ) Book3 を追加オープン Book3 ではメニュー無し
( 5 ) Book2 / Book3 をクローズ Book1ではメニューが残っている
( 6 ) Book1 でエクセル終了 Excel15.xlb からメニュー情報が 削除されない
( 7 ) エクセル再起動 ( Book1 をオープン ) メニューが残っている ( アドインは解除状態 )
( 8 ) Book1 でアドイン登録 メニューが 同一名 で 重複作成されます
 
-- 解除 Case 5 --
( 1 ) エクセル を 起動 ( Book1 を オープン ) メニュー有り
( 2 ) Book2 を追加オープン メニュー有り
( 3 ) Book2 でアドイン解除 Book2 のメニューが消えます/
Book1 ではメニューが残っている
( 4 ) Book2 をクローズ Book1ではメニューが残っている
( 5 ) Book3 を追加オープン Book3 にもメニューが表示される
( 6 ) エクセル終了 ( Book1 / 3 共にクローズ ) Excel15.xlb からメニュー情報が 削除されない
( 7 ) エクセル再起動 ( Book1 をオープン ) メニューが残っている ( アドインは解除状態 )
( 8 ) Book1 でアドイン登録 メニューが 同一名 で 重複作成されます

(補) 「同一名で重複登録される」という問題は、アドイン側で
          CommandBarメニューの作成前に『メニューの存在確認』を行なう
      というマクロにしてあれば回避できます。
      kt関数アドイン では、その対策を行なっていますので重複登録は起こりません。


[ この場所への リンク ]   

7.バグか?  仕様か?

アドイン登録後に、即座にリボンに反映されないという点は、下記ドキュメントに記述されている
ように『仕様』であろうと思います。
      [ Excel の単一ドキュメント インターフェイスのプログラミング ]
      https://msdn.microsoft.com/ja-jp/library/office/dn251093.aspx
   
  SDI の 問題の解決策
      ・ コマンド バー コードおよび XLA ファイルによって Excel ブックに追加されたツールバーは、
        ブック を閉じて再び開くまで表示されません


      [ KB2761240 ]
      Excel2013以降で、Excelアドインのコマンドバーは、アドインを
      ロードまたはアンロードするときに自動的に表示または削除されません
      https://support.microsoft.com/ja-jp/kb/2761240
   
  回避策
      問題 1 を回避するには、すべての開いているブックを閉じ、Excel を再起動します。



しかし、
      Excelの環境設定ファイル(Excel15.xlb)に「更新内容が記録されない」
      という事に起因して、アドインタブが表示されない/削除されない
という挙動については【バグ】であろうと思います。

この問題が無ければ、[ Temporary:=False ] メニューであっても、メニュー更新後に「エクセルの再起動」
さえ行っておけば、常にアドインタブへ反映されていた筈ですから・・・

もっとも、例え「バグ」であったとしても、この問題が修正される可能性は無いでしょう(CommandBar が
既に”古い機能”という扱いですから)。アドインを利用するユーザーには、前述の手順でアドイン
登録を実施するよう指導してください。



[ この場所への リンク ]   

8.[ Temporary:=True ] メニューに『一時的アドイン解除処理』が及ぼす影響  ( 2018/5/8 追記 )
      (この節はExcel2013以降を対象にしています)

5節 では、[ Temporary:=True ] タイプに対して
      このタイプのアドインメニューは、エクセルを再起動すれば
      全てのワークブックウィンドウに必ず反映されます
と説明しました。

しかし、更に調査を進めた結果、そのアドインブックの メニュー作成処理と併せて
『一時的なアドイン解除処理』も行っている
場合には、必ずしも上記の結果になら
ないケースが有る事が判明しました。

アドイン解除とメニュー作成という2つの処理に対して、その実行タイミングの前後関係
から、下記の4パターンが考えられます。

-- タイプ [ Nothing ] --    アドイン解除処理が無い
Private Sub Workbook_Open()
    【 CommandBar メニュー作成処理
End Sub

-- タイプ [ Inside ] --    アドイン解除処理の内側でメニュー作成
Private Sub Workbook_Open()
    If (ThisWorkbook.IsAddin = True) Then
        Application.ScreenUpdating = False
        ThisWorkbook.IsAddin = False
        -- MacroOptions 等 --
       【 CommandBar メニュー作成処理
        ThisWorkbook.IsAddin = True
        ThisWorkbook.Saved = True
        Application.ScreenUpdating = True
    End If
End Sub

-- タイプ [ After ] --     アドイン解除処理の後でメニュー作成
Private Sub Workbook_Open()
    If (ThisWorkbook.IsAddin = True) Then
        Application.ScreenUpdating = False
        ThisWorkbook.IsAddin = False
        -- MacroOptions 等 --
        ThisWorkbook.IsAddin = True
        ThisWorkbook.Saved = True
        Application.ScreenUpdating = True
    End If

    【 CommandBar メニュー作成処理
End Sub

-- タイプ [ Before ] --     アドイン解除処理の前にメニュー作成
Private Sub Workbook_Open()
    【 CommandBar メニュー作成処理

    If (ThisWorkbook.IsAddin = True) Then
        Application.ScreenUpdating = False
        ThisWorkbook.IsAddin = False
        -- MacroOptions 等 --
        ThisWorkbook.IsAddin = True
        ThisWorkbook.Saved = True
        Application.ScreenUpdating = True
    End If
End Sub


  --- 検証マクロ ---
  SDI_AddinTab_Test2.zip ( 99KB )
      I
      +-- MenuTestOpen1_Nothing.xlam
      +-- MenuTestOpen2_Inside.xlam
      +-- MenuTestOpen3_After.xlam
      +-- MenuTestOpen4_Before.xlam
      I
      +-- MenuTestOpen0_FirstDummy.xlam
      +-- MenuTestOpen9_LastDummy.xlam
      I
      +-- MenuAliveCheck.xlsm

  上記 アドインで作成するメニュー名:[ WkshOpenTempT1 & ToolOpenTempT1 ]
  末尾の 数字 が各々1〜4になります。
  Open0_FirstDummy / Open9_LastDummy はアドイン起動順を設ける為のダミーです。
  MenuAliveCheck.xlsm はメニューオブジェクトの存在確認を行なうマクロです。



次に、メニュー作成アドインがアドイン登録されている状況についても下記の3パターンが有ります。
    ( a )  メニュー作成アドインのみがアドイン登録されている。
    ( b )  複数のアドインがアドイン登録されている。
        ( b-1 )  メニュー作成アドインがエクセル起動時のアドイン実行順で1番目。
        ( b-2 )  メニュー作成アドインがエクセル起動時のアドイン実行順で2番目以降。

    「エクセル起動時のアドイン実行順」については下記を参照してください。
    Tips24: Excel2013でエクセル終了時に空ウィンドウが残る/9. アドイン登録と読込順


これらの 4パターン×3パターンの組み合わせでテストを行ったところ、
以下のような結果が得られました。
  ( a ) ( b-1 ) ( b-2 )
  [ Nothing ]  アドイン登録時はメニュー表示なし  /  再起動以降は常時メニュー表示あり
  [ Inside ]  アドイン登録時はメニュー表示なし  /  再起動以降は常時メニュー表示あり
  [ After ]  アドイン登録時にも即時メニュー表示あり  /  再起動以降は常時メニュー表示あり
  [ Before ]  アドイン登録時はメニュー表示なし
 再起動以降は常時メニュー表示あり
 アドイン登録時はメニュー表示なし
 再起動しても全くメニューが表示されない


実際に、メニュー付きアドインブックを作成するに際して、どのパターンを採用するべきなのかを
考えてみます。

先ず、MacroOptions 等のアドイン解除を必要とする処理が無ければ、何も問題が無いことは
確かです。「エクセルを再起動すれば必ず反映される」という認識で間違いないです。

次に、アドイン解除を必要とする処理が有る場合について、残る3パターン(Inside, After,
Before)の何れを採用するべきかです。

[ Before ] が完全に論外なのは誰の眼にも明らかでしょう。

残る [ Inside ] と [ After ] を比べると、「アドイン登録時にも即時にメニューが表示される」
ことから、[ After ] の方が有利に見えます。

しかし、[ Before / b-2 ] のケースを除いた全体で見比べてみれば、圧倒的に「アドイン
登録時はメニュー表示なし、再起動以降は常時メニュー表示あり」が、[ Temporary=True ]
タイプのメニューとしてはスタンダードな挙動に思えます。

[ After ] は例外的な挙動であるという見方をしてみれば、
    偶々、現在はこのような有利な挙動をしているが、今後の何かしらの機能修正があった
    際に、その影響によって、この挙動が崩れてしまう
という可能性もゼロとは言えないでしょう。

--- 結  論 ---
以上の事から、MacroOptions 等のアドイン解除を必要とする処理が有る場合には、
CommandBarメニューの作成は [ Inside ] パターンで行なうべきです。


マクロ開発中( xlsm )の事も考慮すれば、下記のようにすると良いでしょう。

Private Sub Workbook_Open()
    If (ThisWorkbook.IsAddin = True) Then
        Application.ScreenUpdating = False
        ThisWorkbook.IsAddin = False

        Call MacroOptions等()
        Call CommandBarメニュー作成()

        ThisWorkbook.IsAddin = True
        ThisWorkbook.Saved = True
        Application.ScreenUpdating = True
    Else
        Call MacroOptions等()
        Call CommandBarメニュー作成()
    End If
End Sub
- - - - - - - - - - - - - - - - - -
Private Sub MacroOptions等()

End Sub
- - - - - - - - - - - - - - - - - -
Private Sub CommandBarメニュー作成()

End Sub
- - - - - - - - - - - - - - - - - -

( 注意事項 )
  この節で提起した問題を無視して、このマクロだけを見てみてください。直ぐに
      あっ! メニュー作成にはアドイン解除が必要ない。
      If ステートメントの外に出せるじゃないか!
  と気付くと思いますが、それは不具合([ Before ]タイプでメニューが出ない)を
  招きます。将来、マクロを修正する際に、このように考えて不具合を出さないよう、
  しっかりと理由をコメントで記しておくことをお勧めします。

  実際に、私が、このように考えてしまい、その結果不具合を出し、慌てた経験が
  この節の解説を執筆した動機です。


最後に、作成したメニューオブジェクトの経過を追跡したところ、「メニューがあるのに、
アドインタブ(メニュー)が表示されない」のではなく、『メニューオブジェクトそのものが
消されている』という状況のようです。

Workbook_Openイベントプロシージャーの最後(End Sub 直前)では確かに作成した
メニューオブジェクトが存在していますが、Openイベントを抜けた後にはメニューオブ
ジェクトが消えています。

アドインから「エクセルのメニュー管理システム」へのメニューオブジェクトの引き渡しに
失敗(受け取って貰えなかった)した為、メニューオブジェクトがそのまま自然消滅して
しまったようです。

( 注 ) プロシジャー内で メニュー作成した オブジェクト変数の内容 ( Nothing  or  Not nothing ) を 確認 したのなら、
      そうなるのは当たり前だと思うかもしれませんが、この確認テストでは、その都度 「 メニュー名が在るか無いか 」
          Set CBCtrl = Nothing
          Set CBCtrl = MyCB.Controls("WkshOpenTempT4")
          If Not (CBCtrl Is Nothing) Then
              blnAlive = True
          End If
      で調査しましたので結果に間違いはありません。


Home     Back Page     Next Page

ロゴ(ゴールド)   ロゴ(ピンク)

角田 桂一 Mail:addinbox@h4.dion.ne.jp CopyRight(C) 2016 Allrights Reserved.