「商品コードを入力したら商品名と単価を自動で表示させたい」「フォームを開いたときに今日の日付をセットしたい」「必須項目が空のまま保存させないようにしたい」——こうした”フォームを賢く動かす”要求は、Accessのイベントプロシージャを活用することで実現できます。イベントプロシージャとは、フォームやコントロールに設定された特定のタイミング(イベント)で自動的に実行されるVBAコードのことです。
イベントとは「フォームが開かれた」「フィールドの値が変更された」「保存ボタンがクリックされた」といった操作の瞬間のことです。Accessでは各コントロール・フォームに対して「このタイミングにこのコードを実行する」という対応関係を設定できます。マクロよりも柔軟で、VBAの入門としても最初に学ぶべき領域です。MOS Access 365試験(MO-500)のフォームおよびマクロに関するスキル領域でも、イベントを使った処理の実装は重要なテーマです。本記事では、フォームのイベントプロシージャの仕組み・設定手順・主要なイベントの種類・実務での活用パターン・よくあるエラーと対処法・MOS試験攻略のポイントまで、ステップごとに徹底解説します。
「イベントって何?」「VBAエディタをどう開けばいいの?」「AfterUpdateとAfterChangeの違いが分からない」という方は、ぜひ最後まで読んでください。
Accessフォームのイベントとは何か
Accessのフォームでは、ユーザーやシステムの操作に応じて「イベント」が発生します。イベントは発生のタイミングに応じて大きく3種類に分類できます。
| 分類 | 代表的なイベント | 発生のタイミング |
|---|---|---|
| フォーム全体のイベント | OnLoad、OnOpen、BeforeUpdate、AfterUpdate | フォームの開閉・レコード保存の前後 |
| コントロール(テキストボックス等)のイベント | AfterUpdate、OnChange、OnGotFocus、OnLostFocus | 値の変更・フォーカスの移動 |
| ボタンのイベント | OnClick | ボタンのクリック |
各イベントには「イベントプロパティ」という設定欄があり、プロパティシートの「イベント」タブから確認・設定できます。イベントプロパティに「[イベント プロシージャ]」を設定すると、VBAコードと紐付けられます。イベントが発生するたびに設定したVBAコードが実行される仕組みです。
主要なイベントプロパティ一覧
実務でよく使うイベントプロパティを一覧で整理します。フォームレベルのイベントとコントロールレベルのイベントに分けて確認しましょう。
フォームのイベント
| イベントプロパティ名 | 発生タイミング | 主な用途 |
|---|---|---|
| OnLoad(読み込み時) | フォームが開かれてデータが表示される直前 | 初期値のセット・フィールドのロック・表示制御 |
| OnOpen(開くとき) | フォームが開かれる最初のタイミング(フォームのレコードへのアクセス前) | 引数の受け取り・条件によるキャンセル処理 |
| OnClose(閉じるとき) | フォームが閉じられるとき | 終了確認ダイアログ・後続処理の実行 |
| BeforeUpdate(更新前処理) | フォームのレコードが保存される直前 | 入力チェック・保存の中断処理 |
| AfterUpdate(更新後処理) | フォームのレコードが保存された直後 | 保存後の通知・連携処理 |
| OnCurrent(カレントレコード移動時) | レコードを移動するたびに | レコード内容に応じたフィールド表示切替 |
テキストボックス・コンボボックスなどコントロールのイベント
| イベントプロパティ名 | 発生タイミング | 主な用途 |
|---|---|---|
| AfterUpdate(更新後処理) | コントロールの値が変更されてフォーカスが移動した直後 | 関連フィールドの自動入力・計算値の更新 |
| BeforeUpdate(更新前処理) | コントロールの値が確定される直前 | 入力値の検証・変更のキャンセル |
| OnChange(変更時) | テキストボックスの文字が入力されるたびにリアルタイムで | 入力中のリアルタイム検索・文字数カウント |
| OnGotFocus(フォーカス取得時) | コントロールにフォーカスが移ったとき | ヒント表示・背景色変更 |
| OnLostFocus(フォーカス喪失時) | コントロールからフォーカスが離れたとき | 入力完了後の整形処理 |
| OnClick(クリック時) | コントロールをクリックしたとき(ボタンに多用) | フォームを開く・レポート印刷・レコード削除確認 |
| OnDblClick(ダブルクリック時) | コントロールをダブルクリックしたとき | 詳細フォームを開く |
「AfterUpdate」はフォームレベルとコントロールレベルの両方に存在します。フォームの「AfterUpdate」はレコード全体の保存後、コントロールの「AfterUpdate」はそのコントロールの値変更後に発生します。混同しやすいので、どのオブジェクトのAfterUpdateかを常に意識してください。
イベントプロシージャを設定する手順
ステップ1:フォームをデザインビューで開く
ナビゲーションウィンドウでフォームを右クリックし、「デザインビュー」を選択します。フォームのデザインビューが開いたら、イベントを設定するコントロールまたはフォーム全体を選択します。フォーム全体にイベントを設定する場合は、コントロールが何も選択されていない状態(フォームの余白をクリック)でプロパティシートを確認します。
ステップ2:プロパティシートを開く
リボンの「デザイン」タブ→「プロパティシート」をクリックするか、F4キーを押してプロパティシートを表示します。プロパティシートが右側に表示され、現在選択しているオブジェクト(フォームまたはコントロール)の設定一覧が出ます。
ステップ3:「イベント」タブを選択する
プロパティシートの上部に「書式」「データ」「イベント」「その他」「すべて」のタブが並んでいます。「イベント」タブをクリックすると、そのオブジェクトで設定できるイベントプロパティの一覧が表示されます。
ステップ4:目的のイベントに「…」ボタンでVBAエディタを起動する
設定したいイベントプロパティ(例:「読み込み時」)の欄をクリックします。右端に「…(ビルドボタン)」が表示されるのでクリックします。「ビルダーの選択」ダイアログが開いたら「コードビルダー」を選択して「OK」をクリックします。Visual Basic for Applicationsエディタ(VBAエディタ)が起動し、該当するイベントプロシージャの枠が自動で生成されます。
たとえばフォームの「読み込み時(OnLoad)」を設定すると、VBAエディタに次の枠が自動生成されます。
Private Sub Form_Load()
End Sub
ステップ5:プロシージャ内にコードを記述する
Private Sub Form_Load() と End Sub の間にVBAコードを記述します。記述が完了したらVBAエディタを閉じてAccessに戻ります(VBAエディタは閉じずに最小化してもかまいません)。フォームをフォームビューで実行し、イベントが正しく動作するか確認します。
プロシージャ名の命名規則は「オブジェクト名_イベント名」です。フォームのOnLoadなら Form_Load、「商品コード」というコントロールのAfterUpdateなら 商品コード_AfterUpdate というように自動命名されます。この命名規則に従うことでAccessが自動的にイベントと紐付けを行います。
実務パターン1:OnLoadでフォーム起動時に初期化する
フォームが開いたときに「本日の日付を自動でセットする」「特定のフィールドを編集不可(ロック)にする」「管理者権限でない場合はボタンを非表示にする」といった初期化処理は、フォームの「読み込み時(OnLoad)」イベントで実装します。
例1:受注フォームを開いたときに受注日に本日の日付をセットする
Private Sub Form_Load()
' 受注日フィールドに本日の日付をセットする
If IsNull(Me!受注日) Then
Me!受注日 = Date()
End If
End Sub
Me はそのフォーム自身を指すキーワードです。Me!フィールド名 でフォーム上のコントロールにアクセスできます。IsNull() で値が未入力かどうかを確認し、空の場合のみ本日日付をセットしています。新規レコード作成時には確実に今日の日付が入り、既存レコードを開いたときは上書きしない設計です。
例2:一部のフィールドを参照専用(読み取り専用)にする
Private Sub Form_Load()
' 顧客コードフィールドを編集不可にする
Me!顧客コード.Locked = True
Me!顧客コード.BackColor = RGB(240, 240, 240)
End Sub
.Locked = True でコントロールを編集不可にします。あわせて背景色をグレー(RGB値で指定)に変更することで、ユーザーが「このフィールドは入力できない」と視覚的に判断できます。
OnLoadとOnOpenの違い
「開くとき(OnOpen)」はフォームのレコードにまだアクセスできないタイミングで発生します。「読み込み時(OnLoad)」はレコードデータが読み込まれた後に発生するため、フィールドの値を参照・設定する初期化処理には OnLoad が適しています。引数(OpenArgs)を受け取ってフォームの挙動を分岐させる場合は OnOpen が有効です。
実務パターン2:AfterUpdateで関連フィールドを自動入力する
「商品コードを入力したら商品名と単価を自動表示する」処理は、コントロールの「更新後処理(AfterUpdate)」を使うと実現できます。この処理には DLookup 関数を組み合わせます。
例:商品コード入力後に商品名・単価を自動入力する
受注明細フォームに「商品コード」「商品名」「単価」の3つのテキストボックスがあり、「商品マスタ」テーブルに「商品コード」「商品名」「単価」フィールドがある想定です。
Private Sub 商品コード_AfterUpdate()
Dim strCode As String
strCode = Nz(Me!商品コード, "")
If strCode = "" Then
Me!商品名 = Null
Me!単価 = Null
Exit Sub
End If
' 商品マスタから商品名と単価を取得する
Me!商品名 = DLookup("商品名", "商品マスタ", "商品コード = '" & strCode & "'")
Me!単価 = DLookup("単価", "商品マスタ", "商品コード = '" & strCode & "'")
If IsNull(Me!商品名) Then
MsgBox "商品コード「" & strCode & "」は登録されていません。", vbExclamation
Me!商品コード = Null
Me!商品コード.SetFocus
End If
End Sub
ポイントを整理します。
| コード要素 | 役割・説明 |
|---|---|
| Nz(Me!商品コード, “”) | Null値を空文字に変換。未入力(Null)の場合に後続処理がエラーになるのを防ぐ |
| DLookup(“商品名”, “商品マスタ”, …) | 商品マスタテーブルから条件に合致する商品名を1件取得する |
| IsNull(Me!商品名)のチェック | DLookupが値を見つけられなかった(存在しない商品コード)場合の処理 |
| Me!商品コード.SetFocus | エラー時に入力欄に自動でフォーカスを戻し、修正を促す |
商品コードが数値型の場合は条件文の引用符が不要で "商品コード = " & strCode と書きます。文字列型の場合はシングルクォートで囲む必要があります("商品コード = '" & strCode & "'")。フィールドのデータ型を確認してから書き分けてください。
実務パターン3:BeforeUpdateで入力チェックを行う
「必須項目が未入力のまま保存させたくない」「数量フィールドに0以下の値を入力させたくない」といった入力検証は、フォームの「更新前処理(BeforeUpdate)」で実装します。BeforeUpdateの引数 Cancel を True にすると、レコードの保存をキャンセルできます。
例:必須項目チェックと数値範囲チェック
Private Sub Form_BeforeUpdate(Cancel As Integer)
' 必須項目チェック
If IsNull(Me!顧客名) Or Me!顧客名 = "" Then
MsgBox "顧客名は必須入力です。", vbExclamation
Me!顧客名.SetFocus
Cancel = True
Exit Sub
End If
' 数値範囲チェック
If IsNull(Me!数量) Or Me!数量 <= 0 Then
MsgBox "数量には1以上の値を入力してください。", vbExclamation
Me!数量.SetFocus
Cancel = True
Exit Sub
End If
End Sub
Cancel = True を設定すると、レコードの保存が中断され、フォームはそのまま編集状態に戻ります。MsgBox でエラー内容をユーザーに伝え、問題のあるフィールドに .SetFocus でフォーカスを移すことで、修正しやすい状態を作ります。
BeforeUpdateはフォームレベルとコントロールレベルの両方に存在します。フォームの BeforeUpdate はレコード全体の保存前、コントロールの BeforeUpdate は個別フィールドの値確定前に動作します。「フォーム保存時にまとめてチェックしたい」場合はフォームの BeforeUpdate、「入力直後にそのフィールドだけチェックしたい」場合はコントロールの BeforeUpdate を使います。
実務パターン4:OnClickでボタン処理を実装する
「印刷ボタンをクリックしたらレポートを開く」「閉じるボタンをクリックしたら確認ダイアログを表示してからフォームを閉じる」といった処理は、ボタンの「クリック時(OnClick)」イベントで実装します。
例1:レポートを開く印刷ボタン
Private Sub btn印刷_Click()
DoCmd.OpenReport "受注レポート", acViewPreview, , "受注ID = " & Me!受注ID
End Sub
DoCmd.OpenReport でレポートを開きます。第2引数 acViewPreview は印刷プレビューで開く指定です(acViewNormal にすると直接印刷)。第4引数の Where 条件で現在フォームで表示中のレコードに対応するレポートページだけを表示しています。
例2:確認ダイアログを表示してからフォームを閉じる
Private Sub btn閉じる_Click()
Dim answer As Integer
answer = MsgBox("フォームを閉じますか?", vbYesNo + vbQuestion, "確認")
If answer = vbYes Then
DoCmd.Close
End If
End Sub
MsgBox の戻り値で「はい」か「いいえ」を判断し、「はい」を選んだ場合のみ DoCmd.Close でフォームを閉じます。誤操作によるフォームの意図しない終了を防ぐシンプルな実装です。
例3:フィルタボタン——現在のレコードに絞り込む
Private Sub btn同担当で絞込_Click()
Me.Filter = "担当者名 = '" & Me!担当者名 & "'"
Me.FilterOn = True
End Sub
Me.Filter にSQL風の条件文字列をセットし、Me.FilterOn = True でフィルタを有効にします。フォーム上で現在表示中の担当者と同じ担当者のレコードだけに絞り込む処理です。フィルタを解除するには Me.FilterOn = False を実行します。
OnCurrentイベントでレコード移動時の表示を切り替える
「ステータスが"完了"のレコードを開いたときは編集ボタンを非表示にする」「新規レコードのときは一部フィールドを初期化する」といった処理は、フォームの「カレントレコード移動時(OnCurrent)」イベントで実装します。OnCurrent はフォームが開かれたときと、レコードナビゲーションボタンで次・前のレコードに移動するたびに発生します。
Private Sub Form_Current()
' 完了ステータスのレコードは編集ボタンを非表示にする
If Me!ステータス = "完了" Then
Me!btn編集.Visible = False
Else
Me!btn編集.Visible = True
End If
' 新規レコードの場合は受付日を本日の日付にセットする
If Me.NewRecord Then
Me!受付日 = Date()
End If
End Sub
Me.NewRecord は現在のレコードが新規レコードかどうかを示すプロパティで、True の場合は新規レコードです。.Visible = False でコントロールを非表示に、.Visible = True で表示に切り替えられます。OnCurrent はフォームを開いた瞬間にも発生するため、OnLoad と組み合わせることなく初期表示の制御も担えます。
よくあるエラーと対処法
イベントプロシージャを実装するときに発生しやすいエラーと対処法をまとめます。
| 症状・エラー | 原因 | 対処法 |
|---|---|---|
| イベントが発生しない(コードが実行されない) | イベントプロパティに「[イベント プロシージャ]」が設定されていない | プロパティシートの「イベント」タブで対象イベントに「[イベント プロシージャ]」と表示されているか確認し、「...」ボタンで再設定する |
| 実行時エラー 2465「フィールドが見つかりません」 | Me!フィールド名 のフィールド名がフォーム上のコントロール名と一致していない | プロパティシートの「その他」タブで「名前」欄を確認し、コントロールの名前とコード内のフィールド名を一致させる |
| DLookupがNullを返す | 条件文のデータ型が一致していない(文字列型なのにクォートなし等) | テーブルのフィールドデータ型を確認し、文字列型はシングルクォートで囲む。数値型はクォート不要 |
| BeforeUpdateのCancelが機能せず保存される | Cancel引数の型が Integer なのに Boolean 扱いしているなどの誤り | Cancel = True の後に Exit Sub を記述して処理を終了させる |
| 無限ループでフォームが固まる | AfterUpdateイベント内でフィールドを更新したため再びAfterUpdateが発生する | コントロールの更新前に Me!コントロール名.AfterUpdate を一時的に無効化するか、更新のトリガーにならない方法でフィールドを設定する(例:DoEventsを使わない設計に変更) |
| 「コンパイルエラー:変数が定義されていません」 | Option Explicitが設定されていて変数が宣言されていない | プロシージャの先頭にDim変数宣言を追加する |
最も多いトラブルは「コントロール名の不一致」です。VBAコード内で参照するコントロール名が、プロパティシートの「名前」欄と完全に一致しない(スペースの有無・全角半角の違い等)場合にエラーが発生します。コードを書く前にフォームのデザインビューで各コントロールの「名前」プロパティを確認する習慣をつけましょう。
MOS Access試験でのイベントプロシージャ関連の出題ポイント
MOS Access 365試験(MO-500)のフォームおよびマクロに関するスキル領域では、イベントの設定・動作確認・基本的なプロシージャの修正が出題範囲に含まれます。試験本番で操作を迷わないよう、以下のポイントを押さえておきましょう。
- プロパティシートの「イベント」タブの場所:デザインビューで対象オブジェクトを選択→F4キーでプロパティシートを開く→「イベント」タブをクリック、という手順を確実に覚える
- 「...」ボタンからVBAエディタを起動する操作:イベントプロパティの欄をクリック→右端の「...」ボタンをクリック→「コードビルダー」を選択→OK、という手順を体験的に習得する
- [イベント プロシージャ]の表示確認:イベントプロパティに「[イベント プロシージャ]」と表示されていればVBAコードが設定されている証拠。表示が空欄の場合はコードが紐付いていない
- プロシージャ名の命名規則:「オブジェクト名_イベント名」という自動命名のルールを理解し、手動修正を避ける
- DLookup関数の基本書式:DLookup("取得フィールド名", "テーブル名", "条件") の3引数の役割を整理する
- Cancel = Trueの使い方:BeforeUpdateでCancel = Trueを設定すると保存がキャンセルされることを理解する
- Me!コントロール名の書き方:Meキーワードがフォーム自身を指すこと、「!」でコントロール名を指定することを確認する
MOS試験 イベントプロシージャ操作チェックリスト
| 確認ポイント | 操作内容 | 難易度 |
|---|---|---|
| プロパティシートの開き方 | デザインビューでF4キー、または「デザイン」タブ→「プロパティシート」をクリック | ★☆☆ |
| イベントタブへの切り替え | プロパティシート上部の「イベント」タブを選択できる | ★☆☆ |
| VBAエディタの起動 | イベント欄の「...」→「コードビルダー」→OKでVBAエディタが開く | ★☆☆ |
| OnLoadの設定 | フォームの「読み込み時」イベントに初期化コードを記述できる | ★★☆ |
| コントロールAfterUpdateの設定 | テキストボックスの「更新後処理」にDLookupを使った自動入力コードを記述できる | ★★☆ |
| BeforeUpdateによる入力チェック | フォームの「更新前処理」でIsNullチェックとCancel=Trueを使った保存制御ができる | ★★☆ |
| OnClickのボタン処理 | ボタンの「クリック時」にDoCmd.OpenReport等の処理を記述できる | ★★☆ |
| OnCurrentの設定 | フォームの「カレントレコード移動時」を使ってレコードごとの表示切替ができる | ★★★ |
MOS試験のフォームイベント関連問題では、「既存のイベントプロシージャを修正する」パターンと「新しいイベントを追加設定する」パターンが出題されます。試験対策としては、自分でサンプルフォームを作成し、OnLoad・AfterUpdate・BeforeUpdate・OnClickの4つを実際に記述して動作確認する練習が最も効果的です。
受験料は2026年7月時点で一般価格12,980円(税込)・学割価格9,680円(税込)です。試験時間は50分、採点は1,000点満点で実施されます。合格点は非公表で550点~850点が目安とされています。合格率は公表されていません。
まとめ:イベントを起点にフォームを「賢く動く」業務ツールに育てる
本記事のポイントをまとめます。
- イベントとは:ユーザーやシステムの操作に応じてAccessが自動で検知するタイミングのこと。フォームの開閉・値の変更・ボタンのクリックなどが代表的なイベント
- 設定手順:デザインビューで対象オブジェクトを選択→F4キーでプロパティシート→「イベント」タブ→目的のイベント欄の「...」ボタン→「コードビルダー」→VBAエディタでコードを記述
- OnLoad:フォーム起動時の初期化(日付自動入力・フィールドロック・表示切替)に使う。フォームレベルのイベント
- コントロールAfterUpdate:フィールド値変更後の自動入力(DLookupで関連データを引く)に使う。コントロールレベルのイベント
- BeforeUpdate:レコード保存前の入力チェックに使う。Cancel = Trueで保存をキャンセルできる。フォームとコントロールの両レベルに存在する
- OnClick:ボタンのクリック処理(レポート開く・フォーム閉じる・フィルタ適用)に使う
- OnCurrent:レコード移動のたびに発生。レコード内容に応じた表示切替・新規レコード時の初期化に活用できる
- よくあるエラー:コントロール名の不一致・DLookupのデータ型ミス・BeforeUpdateのCancel処理の抜け漏れが代表的
- MOS試験対策:プロパティシートの「イベント」タブとVBAエディタの起動手順を確実に習得し、4つの主要イベント(OnLoad・AfterUpdate・BeforeUpdate・OnClick)を繰り返し練習する
イベントプロシージャをマスターすると、Accessのフォームはデータを入力するだけの画面から、自動チェック・自動入力・自動表示切替を備えた業務専用ツールへと進化します。マクロの「条件」設定で対応できない複雑なロジックも、VBAのイベントプロシージャなら柔軟に実装できます。まずは「商品コード入力後にAfterUpdateで商品名を自動入力する」という最も汎用性の高いパターンを実際に手を動かして実装してみてください。一度成功体験を積めば、他のイベントへの応用は一気に広がります。
PR
MOS試験シリーズの対策テキスト。MOS Accessと同じ試験形式・採点システムで実施されるため、本書でMOS試験全体の出題パターンや操作確認の方法を把握しておくと、Access試験対策にも直接応用できます。
PR
改善Excel パフォーマンスを底上げする仕事改善・効率化テクニック
Excelの業務効率化テクニックを体系的に解説した一冊。Accessのフォームイベントによる自動処理と同様に「繰り返し作業を仕組みで解決する」発想が身につきます。Officeツール全体の効率化思考を磨きたい方に最適です。
