【入門編】フォームの「OnCurrent」イベントで制御する、レコードごとの動的なUI制御 – Access VBA解析バイブル

スポンサーリンク

こんにちは!Accessでのデータベース開発、順調に進んでいますか?
マクロの記録から一歩踏み出し、「自分でコードを書いて自由自在にフォームを操りたい」という熱意、最高ですね。その壁を越えようとしているあなたを、私は全力でサポートします。

今回は、Access VBA開発において「絶対に避けて通れない、けれど使いこなせば最強の武器になる」テーマを取り上げます。

それが、フォームの「OnCurrent(カレント時)」イベントを使った、レコードごとの動的なUI制御です。

「レコードが変わるたびに、入力できる項目を変えたい」
「ステータスが『完了』の時だけ、テキストボックスをロックして編集できないようにしたい」

そんな現場の強い要望をスマートに叶える極意を、優しく、そして本質的な部分まで深く解説していきましょう。ここをクリアすれば、あなたの作るAccessアプリは一気に「プロのシステム」へと生まれ変わります。一緒にマスターしていきましょう!

1. なぜ「OnCurrent(カレント時)」なのか?

まず、大前提のお話から。
Accessのフォームを使っているとき、ユーザーは次々とレコードを移動(上下に移動)しますよね。

ここで初学者がやりがちな失敗が、「ボタンを押した時」や「テキストボックスを変更した時」だけに制御を書いてしまうことです。これだと、レコードを移動した瞬間に、前のレコードの制御が次のレコードに引き継がれてしまい、画面がバグだらけになってしまいます。

カレントイベントの本質

「OnCurrent(カレント時)イベント」とは、ユーザーがレコードを切り替えるたびに、Accessが自動的に発火させてくれる「全自動の監視員」のようなものです。

  • レコード1(ステータス:未着手)を表示 = 入力OK!
  • レコード2(ステータス:完了)を表示 = ロック!触らせない!

このように、レコードが切り替わる「その瞬間」に、画面のコントロール(テキストボックスやボタン)の表情をガラリと変えてあげる。これが、動的なUI制御の正体であり、本質です。

2. 実践!「ステータスに応じて入力をロックする」コード

百聞は一見に如かず。具体的なシチュエーションでコードを見てみましょう。

【シチュエーション】
「受注管理フォーム」があるとします。
`txtStatus` というフィールド(テキストボックス)の値が 「完了」 の場合、そのレコードの担当者名(`txtStaff`)や金額(`txtPrice`)を編集不可(ロック)にし、背景色をグレーに変えて視覚的に分かりやすくします。逆に「完了」以外なら編集を許可します。

フォームのモジュールに記述するコード

以下のコードを、対象フォームのVBAエディタ(コードウィンドウ)の `Form_Current` プロシージャに貼り付けてください。

Option Compare Database
Option Explicit

‘ =====================================================================
‘ イベント名:Form_Current
‘ 概要:レコードが移動するたびに実行され、現在のレコードの内容に応じて
‘ コントロールの有効無効・背景色を動的に制御する
‘ =====================================================================
Private Sub Form_Current()

On Error GoTo ErrorHandler ‘ 思わぬエラーでフリーズするのを防ぐお約束

‘ 1. 新規レコード(まだ値が確定していない行)かどうかの判定
‘ 新規行の場合は、制御をリセットして処理を抜けます
If Me.NewRecord Then
Call ResetControls(True) ‘ 入力可能にする
Exit Sub
End If

‘ 2. ステータスフィールドの値によって処理を分岐
‘ Nz関数を使うことで、値がNull(空っぽ)の場合のエラーを完全に防ぎます
If Nz(Me.txtStatus.Value, “”) = “完了” then

‘ — 【パターンA】完了しているレコードの場合:ロックする —
Me.txtStaff.Locked = True ‘ 入力禁止
Me.txtStaff.BackColor = 15132390 ‘ 薄いグレー(背景色)

Me.txtPrice.Locked = True ‘ 入力禁止
Me.txtPrice.BackColor = 15132390 ‘ 薄いグレー

‘ ユーザーへの案内メッセージをステータスバーに表示する小粋な配慮
Me.Application.Echo True
SysCmd acSysCmdSetStatus, “このレコードは「完了」しているため編集できません。”

Else

‘ — 【パターンB】未完了のレコードの場合:入力を許可する —
Me.txtStaff.Locked = False ‘ 入力許可
Me.txtStaff.BackColor = 16777215 ‘ 白(背景色)

Me.txtPrice.Locked = False ‘ 入力許可
Me.txtPrice.BackColor = 16777215 ‘ 白

‘ ステータスバーをクリア
SysCmd acSysCmdClearStatus

End If

Exit Sub

ErrorHandler:
‘ 万が一のエラー時のハンドリング
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “システムエラー”
End Sub

‘ =====================================================================
‘ 補助プロシージャ:コントロールの状態を一括リセットする関数
‘ =====================================================================
Private Sub ResetControls(isEditable As Boolean)
Dim backColorVal As Long

If isEditable Then
backColorVal = 16777215 ‘ 白
Else
backColorVal = 15132390 ‘ グレー
End If

Me.txtStaff.Locked = Not isEditable
Me.txtStaff.BackColor = backColorVal

Me.txtPrice.Locked = Not isEditable
Me.txtPrice.BackColor = backColorVal

SysCmd acSysCmdClearStatus
End Sub

3. コードの重要ポイントを噛み砕く

プログラミング初学者のあなたが「おっ!」と気づいてほしいポイントを3つ解説します。

① `Me.NewRecord` という強力なガード

フォームを開いた直後や、一番下の「新しいレコード行」に移動したとき、まだフィールドには何もデータがありません。ここに上記のコードをそのまま適用すると、未確定のデータに対して誤動作を起こす原因になります。
`If Me.NewRecord Then` を最初に置くことで、「あ、今は新しい行を追加中だな」とVBAに気づかせて、安全に処理をスルーさせることができます。これは実務で絶対に入れるべき鉄則です。

② `Nz()` 関数の魔力

データベースを扱っていると、値が何も入っていない「Null(ヌル)」という状態に足元をすくわれます。`Me.txtStatus.Value = “完了”` と素朴に書いてしまうと、値がNullのときにVBAが機嫌を損ねてエラーを吐くことがあります。
`Nz(対象, “変換後の値”)` を使うことで、「もし値が空っぽだったら、とりあえず空文字 `””` として扱ってね」とVBAに優しく指示を出すことができます。

③ コントロールは「1つ変更したら、必ずもう一方も戻す」

これが今回の最大の罠であり、最も伝えたい知見です。
VBAでコントロールを「ロックした(`Locked = True`)」場合、次のレコードに移動したとき、ロックを「解除(`Locked = False`)」し忘れると、次のレコードまでロックされたままになってしまいます。
だからこそ、`If`文を書いたら必ず `Else` 側(条件に合致しなかった場合の処理)もセットで記述し、すべての状態を明示的にリセットする癖をつけてください。

4. 陥りやすい罠:単票フォームと連続フォームの挙動の違い

ここで、Access開発者全員が一度はハマる「深イイ話」を一つ。

今回ご紹介したコードは、1つのレコードを大きく表示する「単票フォーム」では完璧に美しく動作します。
しかし、エクセルシートのように複数行がズラッと並ぶ「連続フォーム」でこのコードを実行するとどうなるでしょうか?

なんと、「現在フォーカスが当たっている(アクティブな)行だけでなく、フォームに表示されているすべての行の背景色が、一瞬で同じ色に変わってしまう」という現象が起きます。

これは、Accessの連続フォームの構造上の仕様(コントロールのインスタンスが共有されているため)によるものです。
もしあなたが「連続フォームでレコードごとに背景色やロックを変えたい」という高度な要件に直面した場合は、VBAのコードではなく、Accessの機能である「条件付き書式」を使うのが正解です。

  • 単票フォームの複雑な制御 = OnCurrentイベント(VBA)
  • 連続フォームの視覚的ハイライト = 条件付き書式

この使い分けができるようになれば、あなたはもう初学者ではありません。立派なAccessアーキテクトへの道を歩んでいます!

最後に:ここをクリアすれば、もう怖くない!

フォームの `OnCurrent` イベントとコントロールのプロパティ操作。
最初は「英語のプロパティ名がたくさんあって覚えるのが大変だな…」と感じるかもしれませんが、安心してください。動く仕組みが一度わかってしまえば、あとはパーツを組み替えるパズルのようなものです。

「ユーザーが迷わない、直感的で優しい入力画面」を作るために、ぜひ今日のコードをあなたの開発環境で試してみてくださいね。

ここをクリアすれば、Access VBAの基本はバッチリです!
あなたのデータベース開発が、より楽しく、よりクリエイティブなものになりますように。チーフアーキテクトの私から、心から応援しています!

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