【実務・中級編】フォームの「TimerInterval」と「OnTimer」で実現する自動ログアウト機能 – Access VBA解析バイブル

スポンサーリンク

Accessを「放置」させない。極限の自動ログアウト実装術

業務アプリケーションにおいて、「席を離れたユーザーが放置した端末」は最大のセキュリティホールです。共有端末で機密データが画面に映ったまま放置されている光景を、プロフェッショナルとして許容してはいけません。

今回は、Accessの`TimerInterval`と`OnTimer`を駆使し、単に「閉じる」だけでなく、堅牢かつ保守性の高い「自動ログアウト機構」を実装するアーキテクチャを伝授します。

1. なぜ「単純なタイマー」では破綻するのか?

多くの初学者は、タイマーイベントの中に単に `DoCmd.Quit` を書き込みます。しかし、これでは以下のリスクを放置することになります。

  • 入力作業中の強制終了: 編集中のデータが消失し、トランザクションが不整合を起こす。
  • リソースのリーク: 他のフォームが開いている場合、オブジェクトの解放順序が最適化されず、Accessがハングアップする。
  • ユーザー体験の欠如: 「なぜ消えたのか」が分からず、ユーザーが恐怖を感じる。

本質的な設計とは、「アイドル状態の監視」と「終了処理の分離」にあります。

2. 堅牢な自動ログアウト・アーキテクチャ

この実装には「メインの非表示フォーム」を1つ用意し、そこで常時監視を行う手法を推奨します。

実装ステップ

1. 監視用フォームの作成: `frm_Security_Monitor` という名前でフォームを作成(表示は「なし」でOK)。
2. イベントのフック: 全ての主要フォームで「キー入力」や「マウス移動」を検知し、最後に操作した時刻を更新する仕組みを作ります。

実装コード(監視用フォームのモジュール)

‘ 監視用フォーム (frm_Security_Monitor) に記述
Option Compare Database
Option Explicit

‘ 最後に操作があった時刻を保持する変数
Private LastActivityTime As Date
‘ タイムアウトまでの時間(分)
Private Const TIMEOUT_MINUTES As Integer = 10

Private Sub Form_Load()
‘ タイマーを1分間隔 (60000ミリ秒) で設定
Me.TimerInterval = 60000
LastActivityTime = Now()
End Sub

Private Sub Form_Timer()
‘ アイドル時間がタイムアウトを超えたか判定
If DateDiff(“n”, LastActivityTime, Now()) >= TIMEOUT_MINUTES Then
Call PerformSecureShutdown
End If
End Sub

‘ 操作を検知した際に呼び出すパブリック関数
Public Sub ResetTimer()
LastActivityTime = Now()
End Sub

Private Sub PerformSecureShutdown()
‘ 1. 編集中のデータを保存(あるいは破棄)
On Error Resume Next
DoCmd.RunCommand acCmdSaveRecord

‘ 2. メッセージを表示して終了(あるいは静かに閉じる)
MsgBox “長時間操作がなかったため、セキュリティ保護のため自動終了します。”, vbExclamation, “自動ログアウト”

‘ 3. アプリケーションを完全に終了
Application.Quit acQuitSaveAll
End Sub

3. 全フォームで「操作検知」を自動化する

各フォームにコードを書くのは保守性の観点から「悪」です。「全てのフォームに共通する親クラスを作る」のがアーキテクトの仕事ですが、簡易的には以下の手法が最も効果的です。

各フォームの `OnMouseMove` や `OnKeyPress` イベントに、以下の1行を仕込むだけで十分です。

‘ 各フォームのモジュールにて
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
‘ 監視用フォームの関数を呼び出す
If IsLoaded(“frm_Security_Monitor”) Then
Forms(“frm_Security_Monitor”).ResetTimer
End If
End Sub

※ `IsLoaded` 関数は、Accessの標準機能である `CurrentProject.AllForms(“フォーム名”).IsLoaded` をラッパーして作成してください。

4. プロフェッショナルとしての注意点

この設計を採用するにあたり、以下の3点を必ず考慮してください。

  • 排他制御との兼ね合い:

`Application.Quit` は強制力が強いため、バックエンド(SQL Serverや共有ファイル)でレコードロックがかかっている最中に実行されると、データベース側で「ゾンビプロセス」が残る可能性があります。必ず終了前に `DoCmd.RunCommand acCmdSaveRecord` でトランザクションの整合性を保つこと。

  • タイマーの精度:

Accessのタイマーは、重い処理(クエリ実行中など)が走っている間はブロックされます。厳密なセキュリティが求められる場合は、`GetTickCount` API を利用したマルチスレッドに近い時間監視を検討してください。

  • ユーザーへの配慮:

突然消えるのは最悪のユーザー体験です。`TIMEOUT_MINUTES – 1` の時点で「あと1分で終了します」というダイアログを出す設計が、真に使いやすい業務ツールです。

まとめ

「コードを動かす」のは誰にでもできます。しかし、「業務の整合性を守りながら、セキュリティを担保する」のがエンジニアの価値です。

今回紹介した監視フォームによる集中管理は、コードの重複を排除し、保守コストを劇的に下げます。あなたの作るAccessツールが、現場の信頼を勝ち取るための堅牢なシステムとなることを期待しています。

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