Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


4961 / 13645 ツリー ←次へ | 前へ→

【53358】アドインとメニュー表示 kobasan 08/1/5(土) 20:55 質問[未読]
【53361】Re:アドインとメニュー表示 ichinose 08/1/6(日) 9:13 発言[未読]
【53370】Re:アドインとメニュー表示 kobasan 08/1/6(日) 12:31 お礼[未読]

【53358】アドインとメニュー表示
質問  kobasan  - 08/1/5(土) 20:55 -

引用なし
パスワード
   今晩は。

Xボタンを押してデータブックを閉じ、アドインだけを表示したとき 、
"WorkSheet Menu Bar"に追加したメニューをアドインと非アドインの両方でうま
く表示させたいのですが、Xボタンが2種類あるのでうまくいきません。

ウインドウ右上の黒Xボタンを押したときは問題ないのですが、最上部の赤Xボ
タンを押したときは、メニューが消えたりして、期待した動きになりません。
赤Xボタンを押したら、追加メニューが削除されます。

難しいポイントは、
(1)赤Xボタンを押したら、まずアドインのSavedをチェックしてから、データブッ
  クのSavedをチェックしています。この順番が難しいポイントになっています。

(2)Set App = Nothing のタイミングも難しいです。
  [A]案では、赤Xボタンを押してキャンセルしたら、Set App = Nothingがある
  ため、追加したメニューは消えてしまいます。

 [B]案では、App_WorkbookBeforeCloseを使用して、Set App = Nothing を無効
 にしていますが、こうすると、メニューがExcelに残ったりして、全く別のブッ
 クを開いたときメニューが表示されたりして不具合が出ます。

(3)アドインと非アドインの両方でうまく表示させようとしている点も難しくなっ
 ている点です。

(4)アドインからデータブックを複数開くこと想定しています。

解決策がありましたらよろしくお願いします。

'標準モジュールに
Sub Set_MyMenu()
  With MenuBars(xlWorksheet)
    .Reset
    With .Menus.Add("MyMenu")  'メニューを追加
      .MenuItems.Add "画面大小切替", "画面大小切替"
      .MenuItems.Add "アドイン ON/OFF", "AddinONOFF"
      .MenuItems.Add "Bookを開く", "Open_Book"
      ''''
      ''''
    End With
  End With
End Sub


'TisWorkbookモジュールに
Private WithEvents App As Excel.Application

Private Sub Workbook_Open()
  Set App = Excel.Application
  Set_MyMenu
End Sub

--------------------------[A]-----------------------------
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim msg As String
Dim Res As VBA.VbMsgBoxResult
  If Me.Saved = False Then
    msg = "'" & Me.Name & "' への変更を保存しますか?"
    Res = MsgBox(msg, vbYesNoCancel + vbExclamation)
    Select Case Res
      Case vbYes: Me.Save
      Case vbNo: Me.Saved = True
      Case vbCancel
        Cancel = True
        Exit Sub
    End Select
  End If
  '
  Me.Application.CommandBars("WorkSheet Menu Bar").Reset
  Set App = Nothing
End Sub

-------------------------[B]--------------------------
Private Sub App_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
Dim msg As String
Dim Res As VBA.VbMsgBoxResult
  If Wb.Saved = False Then
    msg = "'" & Wb.Name & "' への変更を保存しますか?"
    Res = MsgBox(msg, vbYesNoCancel + vbExclamation)
    Select Case Res
      Case vbYes: Wb.Save
      Case vbNo: Wb.Saved = True
      Case vbCancel
        Set_MyMenu
        Cancel = True
        Exit Sub
    End Select
  End If
  '
  wb.Application.CommandBars("WorkSheet Menu Bar").Reset
  'Set App = Nothing
End Sub

【53361】Re:アドインとメニュー表示
発言  ichinose  - 08/1/6(日) 9:13 -

引用なし
パスワード
   おはようございます。


>Xボタンを押してデータブックを閉じ、アドインだけを表示したとき 、
>"WorkSheet Menu Bar"に追加したメニューをアドインと非アドインの両方でうま
>く表示させたいのですが、Xボタンが2種類あるのでうまくいきません。

↑この「アドインと非アドインの両方でうまく表示させたい」がはっきり意味が
わかりませんが・・・。

>ウインドウ右上の黒Xボタンを押したときは問題ないのですが、最上部の赤Xボ
>タンを押したときは、メニューが消えたりして、期待した動きになりません。
>赤Xボタンを押したら、追加メニューが削除されます。

↑この現象は、理解できます。

よって、

>難しいポイントは、
>(1)赤Xボタンを押したら、まずアドインのSavedをチェックしてから、データブッ
>  クのSavedをチェックしています。この順番が難しいポイントになっています。

>(2)Set App = Nothing のタイミングも難しいです。
>  [A]案では、赤Xボタンを押してキャンセルしたら、Set App = Nothingがある
>  ため、追加したメニューは消えてしまいます。

↑は、再現できました。


>
> [B]案では、App_WorkbookBeforeCloseを使用して、Set App = Nothing を無効
> にしていますが、こうすると、メニューがExcelに残ったりして、全く別のブッ
> クを開いたときメニューが表示されたりして不具合が出ます。

Appは、Excel起動中はNothingしない方法をとります。

ブックによって、メニューを表示・非表示を行うには、

Private Sub App_WorkbookOpen(ByVal Wb As Workbook)

End Sub

で中で判断するという方法はいかがですか?

はっきり全体の仕様がわからないのですが・・・。
アドインのThisworkbookに

'===============================================================
Option Explicit
'===============================================================
Private WithEvents App As Excel.Application
'==================================================================
Private Sub App_WindowDeactivate(ByVal Wb As Workbook, ByVal Wn As Window)
  Application.OnTime Now(), ThisWorkbook.Name & "!thisworkbook.chk"
End Sub
'==================================================================
Private Sub Workbook_Open()
  Set App = Excel.Application
  Set_MyMenu
End Sub
'==================================================================
Private Sub App_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
Dim msg As String
Dim Res As VBA.VbMsgBoxResult
  If Wb.Name = ThisWorkbook.Name Then Exit Sub
  MsgBox Wb.Name & "----" & Wb.Saved
  If Wb.Saved = False Then
    msg = "'" & Wb.Name & "' への変更を保存しますか?"
    Res = MsgBox(msg, vbYesNoCancel + vbExclamation)
    Select Case Res
      Case vbYes: Wb.Save
      Case vbNo: Wb.Saved = True
      Case vbCancel
        Set_MyMenu
        Cancel = True
        Exit Sub
    End Select
  End If
End Sub
'==================================================================
Public Sub chk()
  If ActiveWorkbook Is Nothing Then
    Application.CommandBars("WorkSheet Menu Bar").Reset
    End If
End Sub


標準モジュールには

'======================================
Option Explicit
Sub Set_MyMenu()
  Application.CommandBars("WorkSheet Menu Bar").Reset
  With MenuBars(xlWorksheet).Menus.Add("MyMenu")  'メニューを追加
      .MenuItems.Add "画面大小切替", "画面大小切替"
      .MenuItems.Add "アドイン ON/OFF", "AddinONOFF"
      .MenuItems.Add "Bookを開く", "Open_Book"
      ''''
      ''''
  End With
End Sub

上記のコードで問題点の解決の糸口になりませんか?
(はっきり仕様が見えない箇所があるので↑この表現になりました)

【53370】Re:アドインとメニュー表示
お礼  kobasan  - 08/1/6(日) 12:31 -

引用なし
パスワード
   ichinose さん 今日は。

提示のコードを参考に、手を加え、なんとか望みの動きをするようになりました。
ありがとうございます。

アドインの時、追加メニューが表示されなかったので、黒×ボタンを判定するフラッグを追加して、下記コードで期待通りの動きをするようになったと思います。
使い込んでいる中で、不具合があったら、また検討してみます。
皆様の参考のためにもコードを載せておきます。

>>Xボタンを押してデータブックを閉じ、アドインだけを表示したとき 、
>>"WorkSheet Menu Bar"に追加したメニューをアドインと非アドインの両方でうま
>>く表示させたいのですが、Xボタンが2種類あるのでうまくいきません。
>
>↑この「アドインと非アドインの両方でうまく表示させたい」がはっきり意味が
>わかりませんが・・・。

コードの制作段階ではアドインでは、作りづらいので普通のブックで修正しています。アドインの切り替えは

    ThisWorkbook.IsAddin

の切り替えで行っています。
アドインのブックのみになったときでも、メニューを残したいと言うことです。


>> [B]案では、App_WorkbookBeforeCloseを使用して、Set App = Nothing を無効
>> にしていますが、こうすると、メニューがExcelに残ったりして、全く別のブッ
>> クを開いたときメニューが表示されたりして不具合が出ます。


メニューが残る原因はメニュー作成コードにあることがわかりました。
Dim Pop As CommandBarPopup
  Set Pop = 親.Controls.Add(msoControlPopup, temporary:=True)

のtemporary:=Trueを追加すると直りました。


以下は、取り合えず採用コードです。

Private WithEvents App As Excel.Application
Private BlackX As Boolean  '黒X判定用

Private Sub Workbook_Open()
  Set App = Excel.Application
  Set_MyMenu
  BlackX = False
End Sub

Private Sub App_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
Dim msg As String
Dim Res As VBA.VbMsgBoxResult
  If Wb.Name = ThisWorkbook.Name Then Exit Sub
  BlackX = True
  MsgBox Wb.Name & "----" & Wb.Saved
  If Wb.Saved = False Then
    msg = "'" & Wb.Name & "' への変更を保存しますか?"
    Res = MsgBox(msg, vbYesNoCancel + vbExclamation)
    Select Case Res
      Case vbYes: Wb.Save
      Case vbNo: Wb.Saved = True
      Case vbCancel
        Set_MyMenu
        Cancel = True
        Exit Sub
    End Select
  End If
End Sub

Private Sub App_WindowDeactivate(ByVal Wb As Workbook, ByVal Wn As Window)
  Application.OnTime Now(), ThisWorkbook.Name & "!thisworkbook.chk"
End Sub

Public Sub chk()
  If ActiveWorkbook Is Nothing And BlackX = False Then
    Application.CommandBars("WorkSheet Menu Bar").Reset
    行列番号を表示
  End If
  BlackX = False
End Sub

ありがとうございました。

4961 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free