【入門編】フォームのOnOpenとOnLoadの実行順序を完全理解:初期化処理の配置場所によるエラー回避 – Access VBA解析バイブル

スポンサーリンク

こんにちは! Access VBAの開発現場で、フォームの初期化エラーや「なぜか値が入らない」というタイトルの怪奇現象に頭を悩ませていませんか?

「マクロやなんとなくのコード記述から一歩抜け出して、本格的なシステムを作りたい」
そう願うあなたへ。今回は、Accessのフォームが画面に表示されるまでの「裏側の舞台裏」を完全解剖します。

ここをクリアすれば、Access VBAの基本はバッチリですよ。一緒に、プロのエンジニアへの階段を一段上りましょう!

1. フォームが開くとき、裏側では何が起きているのか?

Accessのフォームを開くとき、VBAの世界ではいくつかのイベント(特定のタイミングで起きる出来事)がバトンリレーのように次々と実行されます。

中でも私たちが最も頻繁に使うのが、`OnOpen``OnLoad` です。この2つの違いと実行順序を正確に理解することが、堅牢なAccessアプリを作るための第一歩です。

実行順序の黄金律

フォームを開いたとき、イベントは以下の順番で流れます。

1. `Open` イベント (扉を開く前の「準備中」)
2. `Load` イベント (家具を配置する「お部屋の設営完了」)
3. `Resize` イベント (窓のサイズ調整)
4. `Activate` イベント (実際に部屋に足を踏み入れる)

私たちが初期化処理で特に注目すべきは、「1. Open」「2. Load」 のツートップです。

2. `OnOpen` と `OnLoad` の決定的な違い

「どちらもフォームが開く時のイベントなら、どこに書いても一緒じゃないの?」
――いいえ、ここがプロとアマの分かれ道です。それぞれの性格を深く知ることで、エラーの起きない美しいコードが書けるようになります。

① `OnOpen` イベント(門番の役割)

  • タイミング: フォームのデータソース(テーブルやクエリ)が読み込まれる、フォームそのものが生成される瞬間に発生します。
  • 最大の武器: イベントプロシージャ内で `Cancel = True` を指定すると、フォームが開くのを物理的に阻止(キャンセル)できます。
  • 向いている処理:
  • 「今日の営業日は休業日だから、このフォームは開かせない」といった入場制限。
  • 外部から渡された引数(`OpenArgs`)のチェック。

② `OnLoad` イベント(家具職人の役割)

  • タイミング: データソースが読み込まれ、コントロール(テキストボックスやボタンなど)がすべてメモリ上に実体化した直後に発生します。
  • 最大の武器: すべての部品が揃っているため、コントロールに対して直接命令ができます。
  • 向いている処理:
  • テキストボックスへの初期値のセット。
  • コンボボックスの選択肢(リスト)の動的な書き換え。
  • ユーザーの権限に応じたボタンの有効/無効の切り替え。

3. やってはいけない!「間違った配置」が引き起こす悲劇

初学者がやりがちなバグの代表格が、「Openイベントの中で、まだ存在しないコントロールをいじってしまう」というものです。

例えば、以下のようなコードを `Open` イベントに書いたとします。

‘ 【やってはいけない例】
Private Sub Form_Open(Cancel As Integer)
‘ まだコントロールが実体化していないのに値を入れようとした!
Me.txtUserName = “管理者” ‘ ここで実行時エラーが発生することがある
End Sub

このコードを実行すると、Accessはこう怒ります。
> 「実行時エラー ‘2450’: 指定した式で参照されている ‘txtUserName’ フォームが見つかりません」

なぜエラーになるのでしょうか?
それは、`Open` イベントの時点では、まだフォームのガワ(器)しか用意されておらず、中のテキストボックスという「家具」がまだ搬入されていないからです。

4. 実践:安全な初期化処理のコード設計

それでは、現場でそのまま使える、美しく安全な初期化処理のサンプルコードを見てみましょう。

今回は、以下のような要件を想定します。
1. `Open` イベントで、今日の曜日をチェックし、特定の曜日はフォームのオープン自体をキャンセルする。
2. `Load` イベントで、コントロールに初期値を設定し、見た目を整える。

Option Compare Database
Option Explicit

‘ =====================================================================
‘ 1. Openイベント:フォームを開くべきかどうかの「門番」
‘ =====================================================================
Private Sub Form_Open(Cancel As Integer)
‘ 例として、もし「日曜日」だったらフォームを開かない仕様にする場合
‘ Weekday関数:1(日曜) 〜 7(土曜)
If Weekday(Date) = vbSunday Then
MsgBox “本日は日曜日のため、この管理画面は開けません。”, vbCritical, “アクセス拒否”

‘ Cancel に True を代入すると、フォームのオープンが中止されます
Cancel = True
Exit Sub
End If

‘ 外部から渡された引数(OpenArgs)のチェックなどもここで行うと安全です
If Not IsNull(Me.OpenArgs) Then
Me.RecordSource = “SELECT FROM T_Employees WHERE Department = ‘” & Me.OpenArgs & “‘”
End If
End Sub

‘ =====================================================================
‘ 2. Loadイベント:部品(コントロール)の初期化を行う「設営隊」
‘ =====================================================================
Private Sub Form_Load()
On Error GoTo ErrorHandler

‘ すでにコントロールが存在しているので、安心して操作できます
Me.txtUserName = Environ(“USERNAME”) ‘ Windowsのログインユーザー名を設定
Me.txtLoginTime = Now ‘ 現在時刻を設定

‘ コンボボックスの初期選択(先頭行を選択状態にするなど)
If Me.cmbStatus.ListCount > 0 Then
Me.cmbStatus.Value = Me.cmbStatus.ItemData(0)
End If

Exit Sub

ErrorHandler:
MsgBox “フォームの初期化中に予期せぬエラーが発生しました。” & vbCrLf & _
エラー詳細: ” & Err.Description, vbCritical, “システムエラー”
End Sub

5. ここをクリアすれば、Access VBAの基本はバッチリ!

今回のポイントをギュッと凝縮して振り返りましょう。

  • `Open` イベントは「門番」: フォームを開くかどうかの判定や、データソースの切り替え(SQLの動的変更)を行う。`Cancel = True` が使えるのはここだけ!
  • `Load` イベントは「設営隊」: コントロールが揃った状態なので、テキストボックスへの値の代入や初期設定はすべてここに書く!

この「役割分担」を頭に叩き込んでおくだけで、Access特有の不可解な実行時エラータスクから解放され、メンテナンス性の高いプロ仕様のデータベースを構築できるようになります。

コードの配置に迷ったら、「この瞬間、そのコントロールはもう存在しているか?」と自分に問いかけてみてください。答えが自ずと見えてくるはずです。

さあ、あなたのAccessアプリを、よりスマートで強固なものにアップデートしていきましょう!

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