
終了時に独自で保存をしたいのですが、
下記のコードだと1回目でキャンセルすると
2回目以降の呼び出し時に全く実行されません。
どこか悪いのかご教示ください。
また、もしご存じであれば
BeforeClose() と Auto_Close() の違い
ThisWorkbook と Me の違い
を教えてください。
よろしくお願いいたします。
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim iAns As VbMsgBoxResult
iAns = MsgBox("'" & Me.Name & "' への変更を保存しますか?")
Select Case iAns
Case vbYes
Call WriteFile
ThisWorkbook.Close savechanges:=False
Case vbNo
ThisWorkbook.Close savechanges:=False
Case vbCancel
Cancel = True
End Select
End Sub
No.4ベストアンサー
- 回答日時:
こんにちは。
> ですが、vbYesとvbNoのとき、なぜかMsgBoxの表示後にExcelの保存確認
> ダイアログまで表示されてしまい、有効に機能していないようなのです。
> 他の何かがまずいのでしょうか。
最初の処理では、イベント機能が有効になっていてWorkbook_BeforeClose
により処理されますが、WriteFileを行ったことにより、イベント機能が
無効になってしまって、Workbook_BeforeCloseではなく、通常の閉じる処理
になっている、ということはないですか?
もしそうなら、WriteFileの処理の方で
ThisWorkbook.Saved = True
Application.EnableEvents = True
というような処理を追加されてみては如何でしょうか?
という事であれば、
もし、ThisWorkbook.Saved = Trueならメッセージを出さずにブックを閉じる
という処理も必要になるかもしれませんね。
ご回答ありがとうございます。
原因はご指摘のイベント機能関連のようでした。
流れとしては
Application.EnableEvents = False
中略
ThisWorkbook.Saved = True
中略
Application.EnableEvents = True
となっていました。コメントアウトすることで正常に動作しました。
イベント内部でこのようなことをするべきでないということでしょうか。
イベント等についてもっと勉強する必要があるようです。
この度はどうもありがとうございました。
おかげさまで解決できました。
No.3
- 回答日時:
>ですが、vbYesとvbNoのとき、なぜかMsgBoxの表示後にExcelの保存確認ダイアログまで表示されてしまい、
>有効に機能していないようなのです。
>他の何かがまずいのでしょうか。
vbNoの時もとなると、正直に言って解りませんm(_ _)m
#Sub Auto_Cose()に何か書いてたりしないですよね。
新規Book&シンプルなコードで試してみると
'ThisWorkbookModule
Option Explicit
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim iAns As VbMsgBoxResult
Debug.Print Me.Saved
iAns = MsgBox("'" & Me.Name & "' への変更を保存しますか?", vbYesNoCancel)
Select Case iAns
Case vbYes
Call test
Me.Saved = True
Case vbNo
Me.Saved = True
Case vbCancel
Cancel = True
End Select
Debug.Print iAns, Cancel, Me.Saved
End Sub
Private Sub test()
MsgBox "test"
Me.Save
End Sub
(結果)
False
6 False True
False
7 False True
False
2 True False
意図した通り動作すると思います。
本番コードに関しては、ブレイクポイント設定してデバッグしてみてください。
ご回答ありがとうございます。
原因はイベント機能関連のようでした。
検証用のコードまで載せていただいて、ありがとうございました。
おそらくend-uさんの思いもよらないようなヘマをしてたんでしょうね、私。 ^^;
また機会がありましたらよろしくお願いいたします。
No.2
- 回答日時:
こんにちは。
書いていたらすでに回答が……(^_^;)
MmsgBoxの引数Buttonsが指定されていないので
Select Case でiAnsを場合分けできないのと、
BeforeCloseイベントの中にCloseメソッドを入れたら
またイベントが発生してしまうというところが修正ポイントです。
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim iAns As VbMsgBoxResult
iAns = MsgBox("'" & Me.Name & "' への変更を保存しますか?", vbYesNoCancel)
If iAns = vbYes Then Call WriteFie
Select Case iAns
Case vbYes, vbNo
Cancel = False
Case vbCancel
Cancel = True
End Select
End Sub
こっちもだらだらと書いてしまいました……。
> BeforeClose() と Auto_Close() の違い
ですが、記述されたブックが他のブックから操作されたかによって
動作が違います。
Auto_OpenやAuto_Closeは、そのブックを自分で開いた時のみ実行されます。
WorkbookOpenやBeforeCloseは、他のブックから操作された時にも実行されます。
例えば、A、B、Cのブックがあって、BにAuto_Closeによる処理を記述し、
CにBeforeCloseによる処理を記述していたとします。
その時、AからBを閉じる命令を実行してもBのAuto_Closeは実行されません。
しかし、AからCを閉じる命令を実行するとCのBeforeCloseが実行されます。
他のブックのマクロを操作する方法としてRunメソッドがありますが、使うのなら
ヘルプで調べてみてください。
> ThisWorkbook と Me の違い
ですが、私もあまり詳しくありませんが、プロパティとキーワードである、というの
がまず違いますね。
ThisWorkbookは、マクロコードが書かれたそのブックを指すプロパティです。
Meは、そのコードが実行されているクラスや構造体を参照するためのキーワードです。
マクロを記述する時、前者はどこでも使用できますが、後者は、クラスとして成り
立っているThisWorkbookモジュールやUserForm1モジュール内では使用できますが、
標準モジュールでは使えません。
つまり、Meキーワードは、ThisWorkbookモジュール内では、Thisworkbookクラスを
参照している、UserForm1モジュールでは、UserForm1クラスを参照している、とい
うことぐらいしかわかりません。
私自身、単一のUserFormを使う場合は、Meキーワードを使う事がありますが、
ThisWorkbookモジュールではMe、標準モジュールではThisWorkbook、って使い分ける
ことはしたことがありません。(混乱してしまいますから。)
この回答への補足
>MmsgBoxの引数Buttonsが指定されていないので
すみません・・・簡略化している際に誤って省いてしまったようです。
実際にはvbYesNoCancelが付いていました。
end-uさんにも回答していることですが、
ThisWorkbook.Saved = True
にしてもそれが有効化していないことに頭を悩ませている状態です。
何か思い当たることがあればご教示お願いいたします。
>Auto_OpenやAuto_Closeは、そのブックを自分で開いた時のみ実行されます。
>WorkbookOpenやBeforeCloseは、他のブックから操作された時にも実行されます。
解りやすいご説明ありがとうございます。
今回のケースではどちらでも問題ないことを知り、安心しました。
>私自身、単一のUserFormを使う場合は、Meキーワードを使う事がありますが、
>ThisWorkbookモジュールではMe、標準モジュールではThisWorkbook、って使い分ける
>ことはしたことがありません。(混乱してしまいますから。)
たしかにあちこち眺めてたら混乱しそうですね。
ThisWorkbookはMeであまり代用しないほうが統一されて良さそうです。
No.1
- 回答日時:
>...1回目でキャンセルすると
>2回目以降の呼び出し時に全く実行されません。
状況が今ひとつ掴めませんが、そのコードでは上手くいかないのは確かです。
Workbook_BeforeCloseは文字通り、Close前処理ですから
コード内でCancel = Trueしなければ、処理が終わればCloseします。
BeforeClose内でCloseメソッドを書く必要はありません。
と、いうよりCloseメソッドを書くとイベント連鎖が発生する事になりますので書きません。
こういう場合、
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim iAns As VbMsgBoxResult
iAns = MsgBox("'" & Me.Name & "' への変更を保存しますか?", vbYesNoCancel)
Select Case iAns
Case vbYes
Call WriteFile
Me.Saved = True
Case vbNo
Me.Saved = True
Case vbCancel
Cancel = True
End Select
End Sub
このように書きます。
SavedプロパティをTrueに変更すれば、そのBookは変更なしと判定されて
保存せずに閉じる事(ThisWorkbook.Close savechanges:=False)ができます。
#余談かもしれませんが、今回のケースではBeforeSaveイベントでCall WriteFileを利用すれば
#Close時は既定の動作で対応できるような気がします。
#(Sub WriteFileの中身と運用がわからないので確実ではないです。深追いするつもりもありません)
>BeforeClose() と Auto_Close() の違い
BeforeCloseはイベントプロシージャで、Auto_Closeは自動実行マクロです。
Excel95以前からある自動実行マクロに対して、BeforeCloseイベントは97から追加されたものです。(多分)
違いなどは↓など参考にしてみてください。
『■ イベントプロシージャを活用しよう!』
http://home.att.ne.jp/zeta/gen/excel/c04p59.htm
>ThisWorkbook と Me の違い
半分パス。(専門家の方のレスをお待ちください)
ThisWorkbookはThisWorkbookプロパティでMeはMeキーワード。
ThisWorkbookはThisWorkbookを指しますが
MeはThisWorkBookモジュールやFormモジュール、Classモジュール内のプロシージャ内で書くと
それぞれのクラス、インスタンスを指します。
#これ以上うまく伝える自信なしm(_ _)m
この回答への補足
ご回答ありがとうございます。
>BeforeClose内でCloseメソッドを書く必要はありません。
>と、いうよりCloseメソッドを書くとイベント連鎖が発生する事になりますので書きません。
言われてみるとその通りですね。。
Me.Saved = True に直したら、2回目以降もうまくいきました。
ですが、vbYesとvbNoのとき、なぜかMsgBoxの表示後にExcelの保存確認ダイアログまで表示されてしまい、
有効に機能していないようなのです。
他の何かがまずいのでしょうか。
>『■ イベントプロシージャを活用しよう!』
>http://home.att.ne.jp/zeta/gen/excel/c04p59.htm
違いが分かりました。単独で使用する際には特に違いはないようですね。
>MeはThisWorkBookモジュールやFormモジュール、Classモジュール内のプロシージャ内で書くと
>それぞれのクラス、インスタンスを指します。
個々のインスタンス自体を指すのですね。ありがとうございます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
先着1,000名様に1,000円分もらえる!
教えて!gooから感謝をこめて電子書籍1,000円分プレゼント
-
マクロのBeforeCloseイベントについて教えて下さい。 ブック1とブック2を同じエクセルで2つ
Visual Basic(VBA)
-
EXCELマクロ Workbook_BeforeClose について
Visual Basic(VBA)
-
Excel VBA BeforeSaveが動作しないことについて
Excel(エクセル)
-
4
VBAで保存しないで閉じると空のBookが残る
Excel(エクセル)
-
5
Excel マクロ 閉じるボタン
Visual Basic(VBA)
-
6
エクセルVBA ブックを閉じる前に確認メッセージを表示したい
Excel(エクセル)
-
7
VBAでイベント処理に複数回入ってしまうのを防ぎたい
Excel(エクセル)
-
8
メッセージボックスに表示する文字を大きくしたい
Excel(エクセル)
-
9
Excel VBAでブックを閉じる時、複数のブックが開いていると・・・。
Excel(エクセル)
-
10
ExcelVBAで質問です。Workbook_openイベントが発生し
その他(Microsoft Office)
-
11
VBAでブックを非表示で開いて処理して閉じる方法
Excel(エクセル)
-
12
[Excel2000]auto_closeを止めさせるには
Excel(エクセル)
-
13
Excel VBA でExcelを終了したいのですが・・
Excel(エクセル)
-
14
'Range'メソッドは失敗しました
Excel(エクセル)
-
15
ユーザーフォームでTextBox1にカーソルを移動したい
Excel(エクセル)
-
16
ユーザーフォームのコピー?
Excel(エクセル)
-
17
EXCEL(VBA) セルをクリックしたときの処理
Excel(エクセル)
-
18
エクセルVBAのイベント処理のタイミングについて
PowerPoint(パワーポイント)
-
19
VBA ユーザーフォームのChangeイベントを停止したい
Access(アクセス)
-
20
EXCEL VBA Workbook_BeforeSaveについて
Excel(エクセル)
関連するQ&A
- 1 【Excel】【VBA】空白のセルに上のデータを入力する方法
- 2 【Excel】【VBA】重複しないリスト作成について
- 3 【Excel】【VBA】 効率の良いカウント処理について
- 4 【図(1)】の値を【図(2)】【図(3)】の該当セ
- 5 【Excel2003】件数を抜き出す方法について
- 6 word、excelで名前を付けて保存しようとすると強制終了
- 7 【EXCEL2003】範囲に含まれた項目を全部抜き出す関数
- 8 【Excel2003】ファイルが異常に重い原因(画像を探す方法)
- 9 【EXCEL】条件に合致するセルの1つ下のセルの合計値を出す方法
- 10 【Excel2003】Excel関数を用いた各種操作について
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
人気Q&Aランキング
-
4
エクセルVBA フォームShowでオ...
-
5
アクセス2000VBA DAOをADOに書...
-
6
別シートのマクロを実行する方法
-
7
Access終了時にマクロまたはVBA...
-
8
エクセルVBAで、ボタンの文字を...
-
9
InputBox内の表示について
-
10
エクセルのマクロボタンが編集...
-
11
ワードでのラベル作成の自動化
-
12
access2010 コマンドまたはアク...
-
13
シート保護を掛けたまま並べ替...
-
14
excelで会議室予約表の作成(マ...
-
15
エクセル VBA SendKeys ループ...
-
16
「Access」のフォームを...
-
17
アクセス:検索フォームボタンに...
-
18
ExcelのVBAでDisplayalertsで警...
-
19
Access2002のマクロ条件について
-
20
AccessでExcelファイルを印刷
おすすめ情報