[[20161112110850]] 『閉じるをキャンセルされた時』(あんこ) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『閉じるをキャンセルされた時』(あんこ)

ブックを閉じる際に何らかの処置行うのは

Private Sub Workbook_BeforeClose(Cancel As Boolean)

 〜何らかの処置〜

End Sub

で可能ですが
処置が終了した後エクセルシート上では
 保存 保存しない キャンセル
の各ボタンが押せる状態になります
キャンセルのボタンを押された場合に別の処置を行いたいのですが
キャンセルボタンを押された事を感知する事は出来ますか?

Private Sub Workbook_Cansel Button

 〜別の処置〜

End Sub
みたいな事なんですが

< 使用 Excel:Excel2010、使用 OS:Windows7 >


こんな感じでは?

Private Sub Workbook_BeforeClose(Cancel As Boolean)

	〜何らかの処置〜
	ここで、終了するか確認
	if 終了しない場合は、 then
		Cancel=True 
		〜別の処置〜 
	end if

End Sub

(マナ) 2016/11/12(土) 11:47


マナさん
まさにその通りなのですが

>if 終了しない場合は、 then

の "終了しない場合は、" はどの様に書けば良いのでしょうか?
質問したかったのはこの書き方です

"終了しない場合は、" = "キャンセルボタンを押された"
ですよね

If Cancel=True Then

  別の処置
End If
でも無い様ですし,,,,

(あんこ) 2016/11/12(土) 12:29


 終了時ではなく、操作中の上書き保存等では BeforeSaveイベントが走りますね。

 でブック終了時には

 ・まず、BeforeClose が走ります。
 ・次に、もし、このブックに変更が加えられていて未保存の場合に、BeforeSave が発生します。
  もし、このブックに変更が加えられていない場合は BeforeSave は発生しません。

 今、やりたいことは ブックに変更が加わったものを 終了させたときの 保存、保存しない、キャンセル の場面で
 なにかしら制御したいということですね。

 このメッセージは BeforeClose ではなく BeforeSave から出されます。
 ただ、BeforeSave 内で、どのボタンがおされたか、これは、きわめて危険で難解なコードをかけば
 取得も可能だと思いますが、おすすめしません。

 ですから、エクセルからのメッセージではなく、自分で MsgBox によるメッセージを出して制御することが
 よろしいのではないかと思います。

 BeforeClose で、次に、保存のための BeforeSave が走るかどうかは、ThisWorkbook.Saved プロパティが
 True か Fasle かで判定できます。 True なら、保存されてしまっていますので、BeforeSaveは走らず
 したがって エクセルからの保存メッセージもでません。False なら 次に、BeforeSave が走り保存メッセージがでるはずです。

 なお、仮に未保存の状態であったときでも BeforeClose で ThisWorkbook.Saved = True とセットすれば
 エクセルは、もう、保存されてしまっていると【勘違い】して、BeforeSave は走りません。(したがってブックは保存されません)

 具体的に、どういった処理をしたいのかが不明ですので具体的なコード提示はできませんが
 申し上げたようなことを利用して、BeforeClose 内で制御されたらいかがでしょう。

(β) 2016/11/12(土) 13:16


こんな感じで考えています。

Dim ret as integer

ret=msgbox("終了しますか",vbYesNo)

if ret<>vbYes then '終了しない場合

	Cancel=true
	〜別の処置〜 
else	'終了するとき
	me.saved=true
end if

(マナ) 2016/11/12(土) 13:18


↑はβさんのコメントにある【勘違い】をさせていますので
保存しないで終了になります。

ret=msgbpx("保存して終了しますか".vbYexNoCancel)

で、3パターンの処理にしたほうが良かったです。

(マナ) 2016/11/12(土) 13:41


 ちょっと【遊び】です。
 標準モジュールに、以下を貼り付けて Test を実行してみてください。
 エクセルからでる保存するかしないかというメッセージと、ほとんど同じ姿のメッセージを出します。

Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long
Private Declare Function SetWinEventHook Lib "user32" _

        (ByVal eventMin As Long, ByVal eventMax As Long, _
        ByVal hmodWinEventProc As Long, _
        ByVal pfnWinEventProc As Long, _
        ByVal idProcess As Long, ByVal idThread As Long, _
        ByVal dwFlags As Long) As Long
Private Declare Function UnhookWinEvent Lib "user32" _
        (ByVal hWinEventHook As Long) As Long
Const WINEVENT_OUTOFCONTEXT = &H0
Const EVENT_SYSTEM_ALERT = &H2
Private Declare Function SetDlgItemText Lib "user32" _
        Alias "SetDlgItemTextA" _
        (ByVal hDlg As Long, ByVal nIDDlgItem As Long, _
        ByVal lpString As String) As Long

Private Sub WinEventProc( _

            ByVal hEvent As Long, ByVal dwEvent As Long, _
            ByVal hwndMsg As Long, ByVal idObject As Long, _
            ByVal idChild As Long, ByVal idThread As Long, _
            ByVal dwmsEventTime As Long)
    UnhookWinEvent hEvent
    SetDlgItemText hwndMsg, vbYes, "保存"
    SetDlgItemText hwndMsg, vbNo, "保存しない"
    SetDlgItemText hwndMsg, vbCancel, "キャンセル"
End Sub

Sub Test()

    Dim ans As Variant
    Dim ansStr As String
    SetWinEventHook EVENT_SYSTEM_ALERT, EVENT_SYSTEM_ALERT, _
                    0, AddressOf WinEventProc, 0, _
                    GetCurrentThreadId(), WINEVENT_OUTOFCONTEXT
    ans = MsgBox(ThisWorkbook.Name & "への変更内容を保存しますか?", vbYesNoCancel Or vbExclamation)
    Select Case ans
        Case vbYes
            MsgBox "保存 が選ばれました"
        Case vbNo
            MsgBox "保存しない が選ばれました"
        Case Else
            MsgBox "キャンセル が選ばれました"
    End Select

End Sub

(β) 2016/11/12(土) 13:56


 Excel2003時代にブック固有のコマンドバーの明示的削除に使ってた考え方です。
 >〜何らかの処置〜 
 の内容によっては、まったく参考にならないし、
 >キャンセルボタンを押された事を感知する
 為のものでもありません。

 あえてBeforeCloseの内部で完結させたくない要件と言ったら、
 それくらいしか思い付かなかったので、一応あげときます。

 趣旨からハズレてたら無視して下さい。

  Private CloseFlg As Boolean

  Private Sub Workbook_BeforeClose(Cancel As Boolean)
      CloseFlg = True 'ブックが閉じられようとした事を認識するだけ
  End Sub

  Private Sub Workbook_Deactivate()
      If CloseFlg Then 'その認識がある場合のみ、
          Call コマンドバー削除
          '実際に閉じられる時にコマンドバーを削除
      End If
  End Sub

  Private Sub Workbook_Activate()
      If CloseFlg Then
          Call コマンドバー作成
          '閉じるのをキャンセルされて、そのまま作業を続行してたら、
          '別のブックに切り替えた時にコマンドバーが消えちゃうので
          '再びこのブックがアクティブになった時にコマンドバーを再作成
          CloseFlg = False 'して、閉じられようとしたフラグを初期化
      End If
  End Sub

(鈴) 2016/11/12(土) 21:39


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.