Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
  • ベストアンサー

エクセルでWorkbook_BeforeSaveイベントについての疑問

エクセル2000です。 http://odn.okwave.jp/qa3608360.html の関連質問ですが、これだけでも結構ですのでなにとぞご教示ください。 標準モジュールに以下の3つのマクロを書きました。 Sub text_表示() MsgBox "表示させました。" End Sub Sub text_非表示() MsgBox "非表示にしました。" End Sub Sub 保存() ActiveWorkbook.Save End Sub ThisWorkBookモジュールにこう書きました。 Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) Call text_表示 Application.OnTime Now, "text_非表示" End Sub これで、手動でBOOKを保存すると、まず、MsgBox "表示させました。" そして MsgBox "非表示にしました。" が実行され、当然ながら書いたとおりの働きをします。 ところが、Sub 保存() でマクロからBOOKを保存すると、MsgBox "表示させました。" だけが実行され、MsgBox "非表示にしました。"は実行されません。 どうして、Application.OnTime Now, "text_非表示"は無視されたのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.3

ユーザー定義関数をワークシートで使った場合、その関数内に Excel を 操作するコマンド(OnTime なども)無視されますので、それに似た Excel の制限事項なのかと考えました。 #2 の回答は、全然無関係のことだったのかもしれませんね。 すみません。 > そこから先のコマンドで行なった結果は保存したくないからなのです。 BeforeSave イベント内で   Cancel = True として一度保存をキャンセルし、必要なタイミングで自前で保存処理を 行うのではダメなのですか? Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)   Cancel = True   Range("A1").Value = "保存される"   Application.EnableEvents = False   ThisWorkbook.Save   Application.EnableEvents = True   Range("B1").Value = "保存されない"   ThisWorkbook.Saved = True End Sub

merlionXX
質問者

お礼

何度も有難うございます。 > 一度保存をキャンセルし、必要なタイミングで自前で保存処理を > 行うのではダメなのですか? (^0_0^)ナルホド  目からウロコが・・・・。 素晴らしい解決策です。 KenKen_SPさま、いつも有難うございます。

すると、全ての回答が全文表示されます。

その他の回答 (2)

  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.2

仕様でしょう。 プログラムでブックを保存する場合、BeforeSave イベント内に記載された メニューコマンドは無視されるようです。 恐らく、別スレッドで保存コマンドが実行(非同期)されるようですから 保存中にブックに変更があっては困るからではないかと。(推測・未確認) それで、そのような可能性のあるコマンドは無効化されるのでしょうね。  # Msgbox は大丈夫なんですね。まあ、ブックに変更を与える可能性は  # ありませんが、、中途半端だ。 機械翻訳 http://support.microsoft.com/kb/898511/ja?spid=1743&sid=434 原版 http://support.microsoft.com/kb/898511/en-us 余談: 上記 URL の回避策を引用 この問題を回避するために、手動でブックを保存します。 ( ゜д゜)ポカーン

merlionXX
質問者

お礼

有難うございます。 > プログラムでブックを保存する場合、BeforeSave イベント内に記載された > メニューコマンドは無視されるようです。 メニューコマンドとはApplication.OnTime Now,で実行させるマクロという意味でしょうか? 標準モジュールの方をMsgBoxではなく以下のように変えて Sub text_表示() Cells(2, 2) = "表示" End Sub Sub text_非表示() Cells(3, 3) = "非表示" End Sub ThisWorkBookモジュールも Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) Call text_表示 Call text_非表示 End Sub にすれば、マクロでブックを保存する場合でも両方とも実行されます。 Application.OnTime Now,でやるからいけないのでしょうが、Application.OnTime Nowを使うのは、そこから先のコマンドで行なった結果は保存したくないからなのです。

すると、全ての回答が全文表示されます。
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.1

>どうして、Application.OnTime Now, "text_非表示"は無視されたのでしょうか? 「Application.OnTimeが有効なのは、ユーザー関数を実行していない時だけだから」です。 手動で保存した場合、タイマーが有効になるのは、Workbook_BeforeSaveを抜けた直後です。そして、その瞬間は、まだ「Now」です。つまり、Sub text_非表示()が即座に呼ばれます。 ユーザー関数のSub 保存()で保存した場合、タイマーが有効になるのは、Sub 保存()を抜けた直後です。そして、その瞬間は、もう「Workbook_BeforeSaveの中でApplication.OnTimeで指定したNowを過ぎている」のです。 試しに、そのまま24時間放置してみましょう。「23時間59分59秒+限りなく1秒に近い時間後」の「Nowと同じ時刻になった瞬間」にSub text_非表示()が呼ばれる筈です。 「殆どの場合、Application.OnTimeにNowを指定すると、指定の時刻は24時間後になる」と言う事を覚えておきましょう。 なお「処理が遅いパソコン」を使用した場合、手動でBOOKを保存した場合も「Workbook_BeforeSaveを抜けた直後には、もうNowの時刻を過ぎている」ので、Sub text_非表示()が呼ばれるのは24時間後になります(質問者さんのパソコンが「偶然、間に合うだけの処理速度性能を持っていただけ」の話で、どのパソコンでも間に合うとは限りません)

merlionXX
質問者

お礼

さっそく有難うございます。 Workbook_BeforeSaveの中でApplication.OnTimeで指定したNowを過ぎているなら、ずらせばいいんですよね? ためしに10秒後としてみました。 手動ではそうなりました。ところがSub保存()では相変わらず作動しません。 どうしてでしょうか? コード↓ Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) Call text_表示 Application.OnTime Now + TimeValue("00:00:10"), "text_非表示" End Sub

すると、全ての回答が全文表示されます。

関連するQ&A