〖ExcelVBA〗一定時間操作がなければ自動保存するマクロ|Excelを開いたまま放置しても安心

ExcelVBA

Excelを開いたまま作業していると、こんな不安がありませんか?

  • 作業途中で席を外した
  • 「保存しなきゃ」と思いながら忘れた
  • PCのトラブルやフリーズが怖い

そこで今回は、Excelを開いたまま一定時間操作がなければ自動保存するマクロを紹介します。
「最後の操作から○分経ったら保存する」という仕組みなので、放置しても安心です。


スポンサーリンク
スポンサーリンク

この記事でできること

  • 最後の操作から一定時間経過したら自動保存
  • ブックを開いた瞬間から自動で監視を開始
  • 閉じるときにタイマーを停止(余計な動作を防ぐ)
  • 保存済みブックは自動保存、未保存ブックは保存ダイアログを出さない安全仕様

仕組みの考え方(ざっくり)

このマクロは次の2つで成り立っています。

  • 最後に操作した時刻を記録する
  • 一定間隔で「放置時間」をチェックし、超えたら保存する

定期チェックには Application.OnTime(指定時刻にマクロを動かす機能)を使います。


手順:コードは3か所に貼り付けます

今回は「ThisWorkbook」と「標準モジュール」「使用するシート」の3か所にコードを入れます。


① 標準モジュールに貼るコード(本体)

まずは、標準モジュール(Module)に以下を貼り付けてください。

VBAエディター標準モジュール
Option Explicit

' ===== 設定値(ここだけ調整すればOK) =====
Public Const IDLE_MINUTES As Long = 5         ' 何分操作がなければ保存するか
Public Const CHECK_INTERVAL_SECONDS As Long = 30 ' 何秒ごとにチェックするか
' ============================================

Public gLastAction As Date        ' 最後に操作した時刻
Public gNextCheck As Date         ' 次回チェック予定時刻
Public gAutoSaveEnabled As Boolean ' 監視ON/OFF

' 監視開始(ブックを開いたときに呼ばれる)
Public Sub StartIdleAutoSave()
    gAutoSaveEnabled = True
    gLastAction = Now
    ScheduleNextCheck
End Sub

' 監視停止(ブックを閉じるときに呼ばれる)
Public Sub StopIdleAutoSave()
    On Error Resume Next
    gAutoSaveEnabled = False
    If gNextCheck <> 0 Then
        Application.OnTime EarliestTime:=gNextCheck, Procedure:="IdleAutoSave_Check", Schedule:=False
    End If
    On Error GoTo 0
End Sub

' 操作があったことを記録(イベントから呼ぶ)
Public Sub TouchUserAction()
    gLastAction = Now
End Sub

' 一定間隔で呼ばれるチェック処理
Public Sub IdleAutoSave_Check()

    On Error GoTo Finally

    If gAutoSaveEnabled = False Then GoTo Finally

    ' 放置時間(分)を計算
    Dim idleMinutes As Double
    idleMinutes = (Now - gLastAction) * 24 * 60

    If idleMinutes >= IDLE_MINUTES Then

        ' まだ一度も保存していないブックは、勝手に保存先を決めない(安全のため)
        If Len(ThisWorkbook.Path) = 0 Then
            ' 何もしない(必要なら保存ダイアログを出す運用に変更可能)
        Else
            ' 未保存の変更があるときだけ保存
            If ThisWorkbook.Saved = False Then
                ThisWorkbook.Save
            End If
        End If

        ' 保存したら「最後の操作時刻」を更新して連続保存を防ぐ
        gLastAction = Now
    End If

Finally:
    ' 次回チェックを予約
    If gAutoSaveEnabled Then
        ScheduleNextCheck
    End If

End Sub

' 次回チェックを予約
Private Sub ScheduleNextCheck()
    gNextCheck = Now + TimeSerial(0, 0, CHECK_INTERVAL_SECONDS)
    Application.OnTime EarliestTime:=gNextCheck, Procedure:="IdleAutoSave_Check", Schedule:=True
End Sub

② ThisWorkbook に貼るコード(起動・終了の制御)

次に、ThisWorkbook に以下を貼り付けてください。
これで「開いた瞬間に監視開始」「閉じるときに監視停止」できます。

VBAエディターThisWorkbook
Option Explicit

Private Sub Workbook_Open()
    StartIdleAutoSave
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    StopIdleAutoSave
End Sub

③ どこかのシートに貼るコード(操作があったことを記録)

「最後の操作時刻」を更新するために、シート側のイベントも使います。
まずはよく使う3つだけ入れておくのがおすすめです。

対象シート(例:Sheet1)をVBEで開いて、以下を貼り付けてください。
(複数シートで使う場合は、同じものを各シートに入れるか、運用上よく触るシートだけでもOKです)

VBAエディターSheet1
Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    TouchUserAction
End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    TouchUserAction
End Sub

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    TouchUserAction
End Sub

初心者向け:ここを変えるだけで調整できます

① 何分放置で保存するか

Public Const IDLE_MINUTES As Long = 5

例:10分なら 10 に変更します。

② 何秒ごとにチェックするか

Public Const CHECK_INTERVAL_SECONDS As Long = 30

例:60秒ごとにしたいなら 60 に変更します。


よくある注意点

① 未保存ブック(新規作成直後)は勝手に保存しない

本記事のコードは安全のため、保存先がないブック(ThisWorkbook.Path が空)は自動保存しません。
勝手に保存先を決めると事故につながるためです。

どうしても必要なら「保存ダイアログを出す」運用にできます(応用)。

② OnTime は「Excelが動いている間だけ」実行される

PCがスリープしていたり、Excel自体が固まっている場合は動きません。
ただし通常の作業中の保存忘れ対策としては十分効果があります。

③ 共有・読み取り専用のときは保存できない場合がある

権限や状態によって Save が失敗することがあります。
業務ファイルで使う場合は、まずテストしてから導入するのがおすすめです。


動作確認の手順

  1. ブックを .xlsm 形式で保存
  2. いくつかセルを編集(未保存状態にする)
  3. 何も操作せずに設定分数(例:5分)放置
  4. 自動保存されることを確認

まとめ:放置しても安心な「自動保存」仕組みを作れる

Excelを開いたまま一定時間操作がないときに自動保存する仕組みを入れておくと、

  • 保存忘れが減る
  • 席を外しても安心
  • 作業途中のデータが残りやすい

というメリットがあります。
定型運用のブックや入力作業の多いブックに、ぜひ導入してみてください。

スポンサーリンク
スポンサーリンク
ExcelVBA
いがぴをフォローする

コメント

タイトルとURLをコピーしました