VBAのWorkbook_BeforeSaveイベントについての疑問

このQ&Aのポイント
  • エクセル2000のVBAのWorkbook_BeforeSaveイベントについての疑問です。質問者はThisWorkbookモジュールに記述をし、終了時にSheet2を表示するように設定しています。しかし、標準モジュールの終了マクロを使用して終了すると、Sheet2が表示されず、MsgBoxメッセージが表示されます。なぜなのか疑問です。
  • VBAのWorkbook_BeforeSaveイベントについて、エクセル2000での使用時に疑問があります。ThisWorkbookモジュールに記述をし、Sheet2を表示するように設定しています。しかし、終了マクロを使用して終了すると、Sheet2が表示されず、MsgBoxメッセージが表示されます。なぜ終了マクロを使用すると正しく動作しないのか疑問です。
  • エクセル2000のVBAのWorkbook_BeforeSaveイベントについての質問です。ThisWorkbookモジュールに記述をし、終了時にSheet2を表示するように設定しています。しかし、終了マクロを使用して終了すると、Sheet2が表示されず、MsgBoxメッセージが表示されます。なぜなのか疑問です。
回答を見る
  • ベストアンサー

VBAのWorkbook_BeforeSaveイベントについての疑問

エクセル2000です。 前にも似たような質問をしたのですが理解ができていません。 ThisWorkbookモジュールに以下の記述をし、終了時保存する場合にはSheet2を表に出すようにしました。 Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) Sheets("Sheet1").Range("A65536").End(xlUp).Offset(1).Value = Time() Sheets("Sheet2").Select MsgBox "保存します。" & ActiveSheet.Name Sheets("Sheet1").Range("B65536").End(xlUp).Offset(1).Value = Time() End Sub これで×を押して手動で終了すればそのとおりに働きます。ActiveSheet.Nameも当然Sheet2になります。 ところが、標準モジュールの下記の終了マクロ Sub 終了() ThisWorkbook.Close End Sub で終了しようとすると、A列セルにTime()は記録され、どういうわけかSheet2がSelectされず、MsgBox "保存します。" のメッセージが出て、B列セルにTime()が記録され、保存されます。 ActiveSheet.NameもSheet2ではありません。 つまり、Sheets("Sheet2").Select の部分だけが完全にスキップされてしまうのです。 どうしてでしょうか?

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

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.2

こんばんは。 >Close メソッドでもWorkbook_BeforeSaveイベントでできるのはメッセージボックスの表示とセルへの値の代入だけという理解でいいのでしょうか? 私には、断言できないし、あまり、こういう部分は触れてこなかったですね。 以前も書いたような気がしますが、私は、正直、このBeforeSave イベントに関しては、あまり凝った作り方をしません。 しょせん、Close メソッドで送るなら、その前の処理をしたほうがよいとおもうのです。Workbook_BeforeSaveの範囲って、出来る部分と出来ない部分があったのでは、コードが成り立ちません。 >ThisWorkbookモジュールに以下の記述をし、終了時保存する場合にはSheet2を表に出すようにしました。 それを、あえて、そのまま活かして、終了と保存を別に別けて書いてみました。 '「標準モジュール」 '--------------------------------------------------- Sub 終了()  ThisWorkbook.RunAutoMacros xlAutoClose  ThisWorkbook.Close False End Sub Sub Auto_Close()   Worksheets("Sheet2").Select   If ThisWorkbook.Saved = False Then   Worksheets("Sheet1").Range("A65536").End(xlUp).Offset(1).Value = Time()   MsgBox "保存します。" & ActiveSheet.Name   Worksheets("Sheet1").Range("B65536").End(xlUp).Offset(1).Value = Time()   ThisWorkbook.Save   End If End Sub '「ThisWorkbook モジュールへ」 '--------------------------------------------------- Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)   If Not IsError(Application.Caller) Then    Exit Sub   End If   Worksheets("Sheet2").Select   Worksheets("Sheet1").Range("A65536").End(xlUp).Offset(1).Value = Time()   MsgBox "保存します。" & ActiveSheet.Name   Worksheets("Sheet1").Range("B65536").End(xlUp).Offset(1).Value = Time() End Sub まあ、これはもう織り込み済みということでしたら、無視してしまって構わないです。

merlionXX
質問者

お礼

> しょせん、Close メソッドで送るなら、その前の処理をしたほうがよいとおもうのです。 おっしゃるとおりですね。 ありがとうございます。 今後ともご指導くださいますようお願いいたします。

その他の回答 (1)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.1

こんにちは。 この話は、ここの掲示板でも一度ならず出ていたような気がしますが、 「どうしてでしょうか? 」という解答としては、「仕様だから」ということになりますね。 たぶん、どこかヘルプに書かれていたような気がしますが、一旦、Close メソッドを送り出してしまうと、その後に、通常のユーザーのVBAプロシージャでは、処理は出来ないということです。だから、実際に、Close メソッドの前の部分に、処理用のコードを入れるしかないと思います。 私は、これは、Application 側が用意した範囲のものしか使えないのだろうと思っています。

merlionXX
質問者

お礼

Wendy02さま、いつもありがとうございます。 Close メソッドを送り出してしまうと、その後にVBAプロシージャでは、処理出来ないのなら、セルに値を入れられたりメッセージボックスが出せるのはなぜなんだろうとあらためて不思議に思います。 いろいろ試してみたら、 ThisWorkbook.CloseでやってもWorkbook_BeforeSaveで働いてくれたのは、Sheets("Sheet1").Range("D1").Value = Application.UserNameなどのセルへの値の代入とMsgBoxだけでした。 ActiveWindow.DisplayWorkbookTabs = False Cells.Interior.ColorIndex = 6 Columns("C:C").EntireColumn.ColumnWidth = 2 などは不可で でした。Close メソッドでもWorkbook_BeforeSaveイベントでできるのはメッセージボックスの表示とセルへの値の代入だけという理解でいいのでしょうか?

関連するQ&A

  • エクセルで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_非表示"は無視されたのでしょうか?

  • エクセルVBAでSheet1.ActivateとSheet(n).Activate

    エクセル2000です。 VBAでの疑問点を教えてください。 Sub test1() Sheet1.Activate MsgBox ActiveSheet.Name End Sub これは問題なく作動します。 Sub test2() x = ThisWorkbook.Worksheets.Count For n = 1 To x Sheet(n).Activate MsgBox ActiveSheet.Name Next End Sub これは「SubまたはFunctionがていぎされていません」というエラーになります。 もちろん、 Sub test3() x = ThisWorkbook.Worksheets.Count For n = 1 To x Sheets(n).Activate MsgBox ActiveSheet.Name Next End Sub のように書けばOKなのは存じておりますが、これではSheet名に係らず、左から順番となってしまいます。 Sub test4() x = ThisWorkbook.Worksheets.Count For n = 1 To x Sheets("Sheet" & n).Activate MsgBox ActiveSheet.Name Next End Sub のように明確にシート名として記述すればOKなのですが、それでは、Test1のSheet1.Activate が通って、Sheet(n).Activate が通らないのはなぜでしょう? しょうもない質問でごめんさない。

  • 印刷後のVBAの実行 (3)

    Private Sub Workbook_BeforePrint(Cancel As Boolean) If ActiveSheet.Name = "Sheet1" Then If Range("D6").Value = "" Then Cancel = True MsgBox ("名前を入力してください") Range("D6").Select Exit Sub End If Else If ActiveSheet.Name = "Sheet2" Then If Range("C11").Value = "" Then Cancel = True MsgBox ("受付時間を入力してください") Range("C11").Select Exit Sub End If Else Exit Sub End If End If If Worksheets("Sheet1").Range("D5") = "不要" Then GoTo P1 ActiveSheet.Range("A70:Y70").Copy If Worksheets("Sheet3").Range("A1").Value = "" Then Worksheets("Sheet3").Range("A1").PasteSpecial Paste:=xlPasteValues Else Worksheets("Sheet3").Range("A65536").End(xlUp).Offset(1, 0).PasteSpecial _ Paste:=xlPasteValues End If Application.CutCopyMode = False P1: ActiveSheet.Range("A1").Select End Sub sheet1のD5に「不要」と入っていたら 24~33行目の作業がキャンセルになりますが sheet2のD5にも「不要」と入っていたら、同じ様にキャンセルできる様に出来ますでしょうか? ご回答お願いします

  • 印刷後のVBAの実行 (2)

    Private Sub Workbook_BeforePrint(Cancel As Boolean)   If ActiveSheet.Name = "Sheet1" Then     If Range("D6").Value = "" Then       Cancel = True       MsgBox ("名前を入力してください")       Range("D6").Select       Exit Sub     End If   Else     If ActiveSheet.Name = "Sheet2" Then       If Range("C11").Value = "" Then         Cancel = True         MsgBox ("受付時間を入力してください")         Range("C11").Select         Exit Sub       End If     Else              Exit Sub     End If   End If   ActiveSheet.Range("A70:Y70").Copy   If Worksheets("Sheet3").Range("A1").Value = "" Then     Worksheets("Sheet3").Range("A1").PasteSpecial Paste:=xlPasteValues   Else     Worksheets("Sheet3").Range("A65536").End(xlUp).Offset(1, 0).PasteSpecial _       Paste:=xlPasteValues   End If   Application.CutCopyMode = False   ActiveSheet.Range("A1").Select End Sub 先日、上記のコードを回答者の方から教えてもらい、とても助かっていますが sheet1のD5に「不要」という文字が入っていた場合、 sheet3への貼り付け(23~30行目の作業)をキャンセルして、最後にsheet1のA1を選択するようにはどの様にしたらいいでしょうか?

  • 【VBA】MsgBoxの文字数について

    下記のコードを使い、MsgBoxに 各シートの合計値と、それらの総計 を表示しますが、シート数が膨大の時は、メッセージボックスに収まり切りません。 対処法をご教示願います。 Dim i As Long Dim mMsg As String: mMsg = "" Dim mSum As Long For i = ActiveSheet.Index To Sheets.Count mMsg = mMsg & Sheets(i).Name & " : " & Sheets(i).Cells(Rows.Count, "A").End(xlUp).Offset(0, 4).Value & vbCrLf mSum = mSum + Sheets(i).Cells(Rows.Count, "A").End(xlUp).Offset(0, 4).Value Next Sheets(1).Select MsgBox mMsg & "総計 : " & mSum, vbInformation

  • excel  vba  シートの取り扱い

    Sub   aaa() Worksheets.Add ActiveSheet.Name = "Namefile" ((質問)ここへ適当なコードを追加することによって 以下のThisWorkbook.Sheets(1)というのを、上で追加した Namefileシートを処理することとしたい。 つまり  Namefileシート=ThisWorkbook.Sheets(1) どうすればいいか。よろしくお願いします。) ThisWorkbook.Sheets(1).UsedRange ThisWorkbook.Sheets(1).UsedRange.Delete ThisWorkbook.Sheets(1).Range("B2") = "ファイル名" ThisWorkbook.Sheets(1).Range("C2") = "最終更新日" End Sub

  • VBA beforeprintについて

    Private Sub Workbook_BeforePrint(Cancel As Boolean) If ActiveSheet.Name = "sheet1" Then If Range("M1").Value = "" Then Cancel = True MsgBox ("名前を入力してください") Range("M1").Select Exit Sub End If ElseIf ActiveSheet.Name = "sheet2" Then If Range("A47").Value = 文字 Then Cancel = True    MsgBox ("日付を入力してください") Range("A47").Select Exit Sub End If Exit Sub End If End Sub 上記は印刷をする前に実行されるコードですが、上記を実行して印刷をした後に自動で下記のVBAを実行したいのですが Sub データー取り込み() ActiveSheet.Range("B2000:Z2000").Copy ChDir "\\データーA\データーB\データーC\データーD" Workbooks.Open Filename:="\\データーA\データーB\データーC\データーD\データーシート1.xls" Sheets("顧客データー").Select If Worksheets("顧客データー").Range("B18").Value = "" Then Worksheets("顧客データー").Range("B18").PasteSpecial Paste:=xlPasteValues Else Worksheets("顧客データー").Range("B65536").End(xlUp).Offset(1, 0).PasteSpecial _ Paste:=xlPasteValues End If ActiveWorkbook.Save ActiveWindow.Close End Sub 上記のコードと下記のコードをどのように絡めたらいいのかわかりません。アドバイスお願いします。

  • Web上のエクセルのVBA操作について

    OSはWin2000、エクセルも2000です。 社内のイントラネット上にエクセルのBOOKを置いてあります。 ダウンロードせずにダブルクリックでイントラ上で開いたこのBOOKに対するVBA操作で、以下の3つを試しましたが、すべてエラーになり、プレビューすることができません。 どう直せばよいのでしょうか? Sub test() ActiveSheet.PrintPreview End Sub Sub test2() ThisWorkbook.ActiveSheet.PrintPreview End Sub Sub test3() x = ThisWorkbook.ActiveSheet.Name ThisWorkbook.Sheets(x).PrintPreview End Sub また Sub 終了() ActiveWorkbook.Close (False) End Sub もまったく働きません。 どうやったら終了できますか?

  • エクセルVBAのBeforePrintで

    ThisWorkbookモジュールで Private Sub Workbook_BeforePrint(Cancel As Boolean) If ActiveSheet.Name <> "Sheet1" Then Exit Sub MsgBox "BeforePrintイベント発生" End Sub を使って、Sheet1での印刷のイベントを取得できます。 ただ、指示がPrintなのかPrintPreviewなのかが取得できません。 印刷またはプレビューされる前にどちらの指示なのかを取得する方法がありますか?

  • エクセルVBAの不思議な挙動?

    エクセル2003です。 ThisWorkbookには以下の記述があります。 Private Sub Workbook_BeforePrint(Cancel As Boolean) If ActiveSheet.Name <> "Sheet1" Then Exit Sub If Range("A1").Value = "" Then MsgBox "A1が未入力です" Range("A1").Select Cancel = True End If Application.OnTime Now(), "ページ移動" End Sub 標準モジュールには以下の記述があります。 Sub ページ移動() Sheets("Sheet2").Select Range("A1").Select End Sub Sub プリント() ActiveWindow.SelectedSheets.PrintPreview End Sub これでSheet1を開いた状態でツールバーから印刷プレビュー指示をすると、A1セルが入力済みであればプレビュー画面を出し、プレビューを閉じればSheet2が表示されます。 ところが、同じ状態でツールバーからではなく、マクロ Sub プリント を実行すると、プレビュー画面にはなりますが、プレビューを閉じてもSheet1のままです。 なぜ、 Application.OnTime Now(), "ページ移動" が、有効にならないのでしょうか?

専門家に質問してみよう