Excel 2013 でモーダル ダイアログから開かれたブックのメニューバーやリボンの操作ができずウィンドウを閉じることができない

適用対象: Excel 2013

現象


Microsoft Excel 2013 でモーダル ダイアログを表示し、モーダル ダイアログから新規ブックを作成したり、別のブックを開くと、ブックのメニュー バーやリボンの操作ができず、ブック (ウィンドウ) が閉じられない現象が発生します。

原因


Excel 2013 からウィンドウの管理方法が SDI (Single Document Interface) に仕様変更されました。
複数のブックを開いた場合、ブックごとに独自の最上位ウィンドウを持つ管理方法に仕様変更された影響で、モーダル ダイアログからブックを開くと、Excel 内部のアクティブ ウィンドウ管理状態が適切に更新されないことが原因で発生します。

詳細


例としてブック A から呼び出されたユーザー フォームがモーダル ダイアログになっており、さらに別のブック (例としてブック B) を開くと、ブック B はモーダル ウィンドウで開かれます。
このとき、モーダル ウィンドウの呼び出し元であるブック A は閉じることができない動作自体は、既定の動作です。

ただし、ブック B が開かれた時点で、現在のアクティブ ウィンドウはブック B に切り替わるべきですが、実際に Excel 内部で保持されたアクティブ ウィンドウは、ブック A のままとなっています。
そのため、ブック B を閉じようとしたり、ブック B のメニュー バーやリボンの操作を行うと、現在のアクティブ ウィンドウ (ブック A) に対し処理が実行されます。
しかし、ブック A はモーダル ウィンドウを呼び出しており、コマンドを受け付けられる状態ではないため、ブック A に送られた処理は破棄されます。その結果、ブック B は、メニューバーやリボンの操作ができずウィンドウを閉じることができません。

回避策


2 つの 回避策があります。どちらの方法でも、Excel 内部で持つアクティブ ウィンドウのハンドルがを適切に切り替わり、現象を回避できます。

方法1

ユーザー フォームをモードレス ダイアログで表示し、UserForm_Layout イベントで、一度フォーム自身を非表示に設定してから、再度、モーダル ダイアログとして表示します。 (UserForm_Layout イベントは、フォームの新しい位置の算出と画面の再描画を行うイベントで、フォームにフォーカスがある際に発生するイベントです。)

'UserForm をモードレス ダイアログで表示するように変更します。
Sub ボタン1_Click()
UserForm1.Show 0
End Sub

'UserForm コード内に以下の内容をコピーして貼り付けます。Private Sub UserForm_Layout()

Private Sub UserForm_Layout()

Static fSetModal As Boolean
If fSetModal = False Then
fSetModal = True
Me.Hide
Me.Show 1
End If

End Sub
方法 2
フォーム上のボタンがクリックされた場合に、1 秒後にフォームをアンロードし、ウィンドウの最小化を行い、元の画面サイズに戻す処理を順に行います。

'UserForm コード内に以下の内容をコピーして貼り付けます。

Private Sub CommandButton1_Click()

' 新規ブックを追加します
Workbooks.Add

' 問題を回避するための関数を 1 秒後に起動するように設定します
Application.OnTime Now + TimeValue("00:00:01"), "FixRibbonIssue"

End Sub


'標準モジュール内に以下の内容をコピーして貼り付けます。
Public Sub FixRibbonIssue()
Dim xlTargetWnd As Window
Dim xlOrigWindowState As XlWindowState

' フォームをアンロードします
Unload UserForm1

' 回避のため、ウィンドウを最小化して元に戻します
Set xlTargetWnd = ActiveWindow
xlOrigWindowState = xlTargetWnd.WindowState
xlTargetWnd.WindowState = xlMinimized
DoEvents
xlTargetWnd.WindowState = xlOrigWindowState

End Sub



関連情報


問題の再現手順:

  1. Excel 2013 を起動します。
  2. [開発]-[挿入]-[フォーム コントロール]-[ボタン (フォーム コントロール)] をクリックします。
  3. Sheet1 上にドラッグします。
  4. [マクロの登録] ダイアログが表示されたら、マクロ名が "ボタン1_Click" となっていることを確認し、[新規作成] ボタンをクリックします。
  5. Visual Basic Editor が起動したら、[挿入]-[ユーザー フォーム] をクリックします。
  6. UserForm1 が挿入されます。
  7. [ツール ボックス] から、[コマンド ボタン] をクリックし UserForm1 上にドラッグし、ボタンを追加します。
  8. [Command Button1] をダブル クリックし、以下のコードを挿入します。

    Private Sub CommandButton1_Click()

    Workbooks.Add

    Unload Me
    End Sub

  9. [標準モジュール]-[Module1] に戻り、以下のコードを挿入します。

    Sub ボタン1_Click()
    UserForm1.Show
    End Sub

  10. [ファイル]-[終了して Microsoft Excel へ戻る] をクリックします。
  11. Sheet1 上の [ボタン 1] をクリックします。
  12. UserForm1 ダイアログ上の [Command Button1] をクリックします。
  13. 新規ブック (Book2) が表示されます。
  14. Book2 の閉じるボタンやリボンをクリックします。

結果:

Book2 は閉じられず、リボンをクリックしても操作は行われません。

状況


マイクロソフトでは、この問題をこの資料の対象製品として記載されているマイクロソフト製品の問題として認識しています。