こんにちは!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の基本はバッチリです!
あなたのデータベース開発が、より楽しく、よりクリエイティブなものになりますように。チーフアーキテクトの私から、心から応援しています!
